[osg-users] TransferFunction definition and osgVolume

Alex Taylor alextaylor at gmail.com
Thu Aug 2 09:30:35 PDT 2018

First off, I'm having problems posting to OSG Users with my work email.
Apologies in advance if you receive multiple copies of this same email.

We’re encountering a puzzling behavior in rendering using
RayTracedTechnique and we’ve narrowed it down to what appears to be an
inconsistency in how the TransferFunction passed to osgVolume is defined.

If we use osgVolume::applyTransferFunction

The mapping of our image values to corresponding Vec4 values works
exactly as we would expect. Our TransferFunction is defined as:

    osg::ref_ptr<osg::TransferFunction1D> createTransferFunction(const
uint8_T* xfer_table, const bool useIsosurface)


        osg::TransferFunction1D::ColorMap colorMap;

        for (size_t r = 0; r < 256; ++r){

            size_t rowOffset = r*4;

            float red = static_cast<float>(xfer_table[rowOffset])/255.0f;

            float green =

            float blue = static_cast<float>(xfer_table[rowOffset+2])/255.0f;

            float alpha = (useIsosurface) ? 1.0f :

            colorMap[static_cast<float>(r)/255.0f] =


        osg::TransferFunction1D *transferFunction = new


        osg::ref_ptr<osg::TransferFunction1D> tfSmartPtr = transferFunction;

        return tfSmartPtr;


Here, xfer_table is a 256x4 array, so we are always defining a
TransferFunction that has exactly as many entries as there are
possible values in our volume.

When we attempt to use the “direct” GPU mapping in which we add a
TransferFunction definition to the volume layer:


What we see is that the correspondence between the values in our
[0,255] uint8 volume do not seem to map correctly to the
TransferFunction. For example, if we start with a 200x200x200 volume
where the volume contains only two distinct values: [0,255], where
each value is present in a continuous half of the volume:

We see exactly what we’d expect here, where the alpha map is defined on the
right plot and its uniformly 1 for all volume intensity values.

[image: correctImage.jpg]

Now, if we edit the transfer function such that we wouldn’t expect to see
any of the 255 valued voxels in the volume, we see things don’t render
correctly, you still see the 255 voxels partially.

[image: badImage.jpg]

Again, the exact same transfer function renders as we would expect if we
use osgVolume::applyTransferFunction and render the remapped volume. So, it
seems like maybe the shader used when you do GPU mapping of the transfer
function expects a different convention for the definition of the
TransferFunction map?, but I can’t figure out what that convention is.

Apologies for the length of this question and appreciate any advice people


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.openscenegraph.org/pipermail/osg-users-openscenegraph.org/attachments/20180802/4a659ea6/attachment.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: correctImage.jpg
Type: image/jpeg
Size: 13464 bytes
Desc: not available
URL: <http://lists.openscenegraph.org/pipermail/osg-users-openscenegraph.org/attachments/20180802/4a659ea6/attachment.jpg>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: badImage.jpg
Type: image/jpeg
Size: 13491 bytes
Desc: not available
URL: <http://lists.openscenegraph.org/pipermail/osg-users-openscenegraph.org/attachments/20180802/4a659ea6/attachment-0001.jpg>

More information about the osg-users mailing list