<div dir="ltr"><div style="color:rgb(33,33,33);font-size:13px">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.</div><div style="color:rgb(33,33,33);font-size:13px"><br></div><div style="color:rgb(33,33,33);font-size:13px"><p class="MsoNormal" style="margin:0in 0in 0.0001pt;font-size:12pt;font-family:Calibri,sans-serif"><span style="font-size:11pt">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.<span class="inbox-inbox-m_6956830646083272825inbox-inbox-m_3400983579294090980inbox-inbox-Apple-converted-space"> </span></span></p><p class="MsoNormal" style="margin:0in 0in 0.0001pt;font-size:12pt;font-family:Calibri,sans-serif"><span style="font-size:11pt"> </span></p><pre style="margin:0in 0in 0.0001pt;font-size:10pt;font-family:"Courier New""><span style="font-size:11pt;font-family:Calibri,sans-serif">If we use</span><span style="font-size:11pt"> </span>osgVolume::applyTransferFunction</pre><pre style="margin:0in 0in 0.0001pt;font-size:10pt;font-family:"Courier New""> </pre><pre style="margin:0in 0in 0.0001pt;font-size:10pt;font-family:"Courier New""><span style="font-family:Calibri,sans-serif">The mapping of our image values to corresponding Vec4 values works exactly as we would expect. Our TransferFunction is defined as:</span></pre><pre style="margin:0in 0in 0.0001pt;font-size:10pt;font-family:"Courier New""><span style="font-family:Calibri,sans-serif"> </span></pre><p class="MsoNormal" style="margin:0in 0in 0.0001pt;font-size:12pt;font-family:Calibri,sans-serif"><span style="font-size:10pt;font-family:"Courier New"">    osg::ref_ptr<osg::TransferFunction1D> createTransferFunction(const uint8_T* xfer_table, const bool useIsosurface)</span></p><p class="MsoNormal" style="margin:0in 0in 0.0001pt;font-size:12pt;font-family:Calibri,sans-serif"><span style="font-size:10pt;font-family:"Courier New"">    {</span></p><p class="MsoNormal" style="margin:0in 0in 0.0001pt;font-size:12pt;font-family:Calibri,sans-serif"><span style="font-size:10pt;font-family:"Courier New"">        osg::TransferFunction1D::ColorMap colorMap;</span></p><p class="MsoNormal" style="margin:0in 0in 0.0001pt;font-size:12pt;font-family:Calibri,sans-serif"><span style="font-size:10pt;font-family:"Courier New"">        for (size_t r = 0; r < 256; ++r){</span></p><p class="MsoNormal" style="margin:0in 0in 0.0001pt;font-size:12pt;font-family:Calibri,sans-serif"><span style="font-size:10pt;font-family:"Courier New"">            size_t rowOffset = r*4;</span></p><p class="MsoNormal" style="margin:0in 0in 0.0001pt;font-size:12pt;font-family:Calibri,sans-serif"><span style="font-size:10pt;font-family:"Courier New"">            float red = static_cast<float>(xfer_table[rowOffset])/255.0f;</span></p><p class="MsoNormal" style="margin:0in 0in 0.0001pt;font-size:12pt;font-family:Calibri,sans-serif"><span style="font-size:10pt;font-family:"Courier New"">            float green = static_cast<float>(xfer_table[rowOffset+1])/255.0f;</span></p><p class="MsoNormal" style="margin:0in 0in 0.0001pt;font-size:12pt;font-family:Calibri,sans-serif"><span style="font-size:10pt;font-family:"Courier New"">            float blue = static_cast<float>(xfer_table[rowOffset+2])/255.0f;</span></p><p class="MsoNormal" style="margin:0in 0in 0.0001pt;font-size:12pt;font-family:Calibri,sans-serif"><span style="font-size:10pt;font-family:"Courier New"">            float alpha = (useIsosurface) ? 1.0f : static_cast<float>(xfer_table[rowOffset+3])/255.0f;</span></p><p class="MsoNormal" style="margin:0in 0in 0.0001pt;font-size:12pt;font-family:Calibri,sans-serif"><span style="font-size:10pt;font-family:"Courier New"">           </span></p><p class="MsoNormal" style="margin:0in 0in 0.0001pt;font-size:12pt;font-family:Calibri,sans-serif"><span style="font-size:10pt;font-family:"Courier New"">            colorMap[static_cast<float>(r)/255.0f] = osg::Vec4(red,green,blue,alpha);</span></p><p class="MsoNormal" style="margin:0in 0in 0.0001pt;font-size:12pt;font-family:Calibri,sans-serif"><span style="font-size:10pt;font-family:"Courier New"">        }</span></p><p class="MsoNormal" style="margin:0in 0in 0.0001pt;font-size:12pt;font-family:Calibri,sans-serif"><span style="font-size:10pt;font-family:"Courier New"">        osg::TransferFunction1D *transferFunction = new osg::TransferFunction1D;</span></p><p class="MsoNormal" style="margin:0in 0in 0.0001pt;font-size:12pt;font-family:Calibri,sans-serif"><span style="font-size:10pt;font-family:"Courier New"">        transferFunction->assign(colorMap);</span></p><p class="MsoNormal" style="margin:0in 0in 0.0001pt;font-size:12pt;font-family:Calibri,sans-serif"><span style="font-size:10pt;font-family:"Courier New"">       </span></p><p class="MsoNormal" style="margin:0in 0in 0.0001pt;font-size:12pt;font-family:Calibri,sans-serif"><span style="font-size:10pt;font-family:"Courier New"">        osg::ref_ptr<osg::TransferFunction1D> tfSmartPtr = transferFunction;</span></p><p class="MsoNormal" style="margin:0in 0in 0.0001pt;font-size:12pt;font-family:Calibri,sans-serif"><span style="font-size:10pt;font-family:"Courier New"">        return tfSmartPtr;</span></p><p class="MsoNormal" style="margin:0in 0in 0.0001pt;font-size:12pt;font-family:Calibri,sans-serif"><span style="font-size:10pt;font-family:"Courier New"">    }</span></p><p class="MsoNormal" style="margin:0in 0in 0.0001pt;font-size:12pt;font-family:Calibri,sans-serif"><span style="font-size:11pt"> </span></p><pre style="margin:0in 0in 0.0001pt;font-size:10pt;font-family:"Courier New""><span style="font-family:Calibri,sans-serif">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.</span></pre><pre style="margin:0in 0in 0.0001pt;font-size:10pt;font-family:"Courier New""><span style="font-family:Calibri,sans-serif"> </span></pre><pre style="margin:0in 0in 0.0001pt;font-size:10pt;font-family:"Courier New""><span style="font-family:Calibri,sans-serif">When we attempt to use the “direct” GPU mapping in which we add a TransferFunction definition to the volume layer:</span></pre><pre style="margin:0in 0in 0.0001pt;font-size:10pt;font-family:"Courier New""><span style="font-family:Calibri,sans-serif"> </span></pre><p class="MsoNormal" style="margin:0in 0in 0.0001pt;font-size:12pt;font-family:Calibri,sans-serif"><span style="font-size:10pt;font-family:"Courier New"">        layer->addProperty(new osgVolume::TransferFunctionProperty(volumeProperties.transferFunction.get()));</span></p><p class="MsoNormal" style="margin:0in 0in 0.0001pt;font-size:12pt;font-family:Calibri,sans-serif"><span style="font-size:11pt"> </span></p><pre style="margin:0in 0in 0.0001pt;font-size:10pt;font-family:"Courier New""><span style="font-family:Calibri,sans-serif">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:</span></pre><pre style="margin:0in 0in 0.0001pt;font-size:10pt;font-family:"Courier New""><span style="font-family:Calibri,sans-serif"> </span></pre><p class="MsoNormal" style="margin:0in 0in 0.0001pt;font-size:12pt;font-family:Calibri,sans-serif"><span style="font-size:11pt">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.</span></p><p class="MsoNormal" style="margin:0in 0in 0.0001pt;font-size:12pt;font-family:Calibri,sans-serif"><span style="font-size:11pt"><br></span></p><p class="MsoNormal" style="margin:0in 0in 0.0001pt;font-size:12pt;font-family:Calibri,sans-serif"><span style="font-size:11pt"></span></p><img src="cid:164fb7923cc8e8057841" alt="correctImage.jpg" class="" style="max-width: 100%; opacity: 1;"><br><p></p><p class="MsoNormal" style="margin:0in 0in 0.0001pt;font-size:12pt;font-family:Calibri,sans-serif"><span style="font-size:11pt"></span></p><p class="MsoNormal" style="margin:0in 0in 0.0001pt;font-size:12pt;font-family:Calibri,sans-serif"><br></p><p class="MsoNormal" style="margin:0in 0in 0.0001pt;font-size:12pt;font-family:Calibri,sans-serif"><span style="font-size:11pt">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.</span></p><p class="MsoNormal" style="margin:0in 0in 0.0001pt;font-size:12pt;font-family:Calibri,sans-serif"><span style="font-size:11pt"> </span><span style="font-size:12pt"> </span></p><p class="MsoNormal" style="margin:0in 0in 0.0001pt;font-size:12pt;font-family:Calibri,sans-serif"><span style="font-size:12pt"></span></p><img src="cid:164fb79648fc6262492" alt="badImage.jpg" class="" style="max-width: 100%; opacity: 1;"><br><p></p><p class="MsoNormal" style="margin:0in 0in 0.0001pt;font-size:12pt;font-family:Calibri,sans-serif"><span style="font-size:12pt"><br></span></p><p class="MsoNormal" style="margin:0in 0in 0.0001pt;font-size:12pt;font-family:Calibri,sans-serif"><span style="font-size:11pt">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.</span></p><p class="MsoNormal" style="margin:0in 0in 0.0001pt;font-size:12pt;font-family:Calibri,sans-serif"><span style="font-size:11pt"><br></span></p><p class="MsoNormal" style="margin:0in 0in 0.0001pt;font-family:Calibri,sans-serif"><span style="font-size:14.6667px">Apologies for the length of this question and appreciate any advice people have.</span></p><p class="MsoNormal" style="margin:0in 0in 0.0001pt;font-family:Calibri,sans-serif"><span style="font-size:14.6667px"><br></span></p><p class="MsoNormal" style="margin:0in 0in 0.0001pt;font-family:Calibri,sans-serif"><span style="font-size:14.6667px">Thanks!</span></p><p class="MsoNormal" style="margin:0in 0in 0.0001pt;font-family:Calibri,sans-serif"><span style="font-size:14.6667px"><br></span></p><p class="MsoNormal" style="margin:0in 0in 0.0001pt;font-family:Calibri,sans-serif"><span style="font-size:14.6667px">Alex</span></p></div></div>