<div dir="ltr"><div class="gmail_quote"><div dir="ltr"><span style="color:rgb(0,0,0);font-family:Calibri,Arial,Helvetica,sans-serif;font-size:16px;line-height:24px">For context, I come from an image processing and signal processing background, so computer graphics and OSG are both new to me.</span><br></div><div dir="ltr"><p style="color:rgb(0,0,0);font-family:Calibri,Arial,Helvetica,sans-serif;font-size:16px;line-height:24px">I'm trying to use osgVolume for volume rendering some data. The only real example code I can find out there is the osgvolume example that ships with OSG. I'm a bit confused about the usage model with the various VolumeTechnique classes.</p><p style="color:rgb(0,0,0);font-family:Calibri,Arial,Helvetica,sans-serif;font-size:16px;line-height:24px">I'm working with GL_RGBA uint8 data. In my code, I define a function createTexture3D that creates an osg::Image object. The image is defined as:</p><p style="color:rgb(0,0,0);font-family:Calibri,Arial,Helvetica,sans-serif;font-size:16px;line-height:24px"><strong></strong></p><div style="color:rgb(0,0,0);font-family:Calibri,Arial,Helvetica,sans-serif;font-size:16px;line-height:24px"><div><strong>        osg::ref_ptr<osg::Image> image_3d = new osg::Image;</strong></div><div><strong>        image_3d->allocateImage(nmSAFE_CAST(int, s_nearestPowerOfTwo),</strong></div><div><strong>                nmSAFE_CAST(int, t_nearestPowerOfTwo),</strong></div><div><strong>                nmSAFE_CAST(int, r_nearestPowerOfTwo),</strong></div><div><strong>                desiredPixelFormat, GL_UNSIGNED_BYTE);​</strong><br></div><div><br>When I started with a simple example, FixedFunctionTechnique rendered my data as I expected. See fixedFunctionTechnique.png attached.<br></div></div><p style="color:rgb(0,0,0);font-family:Calibri,Arial,Helvetica,sans-serif;font-size:16px;line-height:24px"><strong>osg::ref_ptr<osgVolume::VolumeTile> tile = new osgVolume::VolumeTile;</strong><br></p><div style="color:rgb(0,0,0);font-family:Calibri,Arial,Helvetica,sans-serif;font-size:16px;line-height:24px"><strong>            volume->addChild(tile.get());</strong></div><div style="color:rgb(0,0,0);font-family:Calibri,Arial,Helvetica,sans-serif;font-size:16px;line-height:24px">            </div><div style="color:rgb(0,0,0);font-family:Calibri,Arial,Helvetica,sans-serif;font-size:16px;line-height:24px"><strong>            osg::ref_ptr<osg::Image> image_3d = createTexture3D(data,xfer_table);</strong></div><div style="color:rgb(0,0,0);font-family:Calibri,Arial,Helvetica,sans-serif;font-size:16px;line-height:24px">            </div><div style="color:rgb(0,0,0);font-family:Calibri,Arial,Helvetica,sans-serif;font-size:16px;line-height:24px"><strong>            osg::ref_ptr<osgVolume::ImageLayer> layer = new osgVolume::ImageLayer(image_3d.get());</strong></div><div style="color:rgb(0,0,0);font-family:Calibri,Arial,Helvetica,sans-serif;font-size:16px;line-height:24px">            </div><div style="color:rgb(0,0,0);font-family:Calibri,Arial,Helvetica,sans-serif;font-size:16px;line-height:24px"><strong>            tile->setLayer(layer.get());</strong></div><div style="color:rgb(0,0,0);font-family:Calibri,Arial,Helvetica,sans-serif;font-size:16px;line-height:24px">                    </div><div style="color:rgb(0,0,0);font-family:Calibri,Arial,Helvetica,sans-serif;font-size:16px;line-height:24px"><strong>            tile->setVolumeTechnique(new osgVolume::FixedFunctionTechnique());</strong></div><div style="color:rgb(0,0,0);font-family:Calibri,Arial,Helvetica,sans-serif;font-size:16px;line-height:24px">            </div><div style="color:rgb(0,0,0);font-family:Calibri,Arial,Helvetica,sans-serif;font-size:16px;line-height:24px"><strong>            // FixedFunctionTechnique turns on GL_LIGHTING, which breaks the color rendering.</strong></div><div style="color:rgb(0,0,0);font-family:Calibri,Arial,Helvetica,sans-serif;font-size:16px;line-height:24px"><strong>            osg::StateSet* stateset = volume->getOrCreateStateSet();</strong></div><div style="color:rgb(0,0,0);font-family:Calibri,Arial,Helvetica,sans-serif;font-size:16px;line-height:24px"><strong>            stateset->setMode(GL_LIGHTING,osg::StateAttribute::OFF | osg::StateAttribute::OVERRIDE);</strong></div><div style="color:rgb(0,0,0);font-family:Calibri,Arial,Helvetica,sans-serif;font-size:16px;line-height:24px"><br></div><div style="color:rgb(0,0,0);font-family:Calibri,Arial,Helvetica,sans-serif;font-size:16px;line-height:24px"><strong>            // Our original implementation positioned the bbox [-0.5,0.5] in each dimension.</strong></div><div style="color:rgb(0,0,0);font-family:Calibri,Arial,Helvetica,sans-serif;font-size:16px;line-height:24px"><strong>            // FixedFunctionTechnique applies the locator matrix to the a unit cube [0 1] in each dimension.</strong></div><div style="color:rgb(0,0,0);font-family:Calibri,Arial,Helvetica,sans-serif;font-size:16px;line-height:24px"><strong>            // To get the equivalent spatial referencing, apply a translation of -0.5 to each dimension.            </strong></div><div style="color:rgb(0,0,0);font-family:Calibri,Arial,Helvetica,sans-serif;font-size:16px;line-height:24px"><strong>            osg::ref_ptr<osg::RefMatrix> matrix = new osg::RefMatrix();</strong></div><div style="color:rgb(0,0,0);font-family:Calibri,Arial,Helvetica,sans-serif;font-size:16px;line-height:24px"><strong>            matrix->makeTranslate(-0.5,-0.5,-0.5);</strong><br></div><p style="color:rgb(0,0,0);font-family:Calibri,Arial,Helvetica,sans-serif;font-size:16px;line-height:24px">I attempted to modify this simple example to use RayTracedTechnique next. When I do that, both the color and the opacity of my volume data is off. In some cases, I see something on the screen (see attached screenshot, in other cases, I don't see anything). I almost feel like somehow my data is outside of an expected colormap/alphamap range, but I can't figure out what's off. In this particular example with an engine block CT dataset and a specific colormap/alphamap, I see what is shown in the attached rayTracedTechnique.png. Here is a partial code listing based on the OSG example:<br></p><p style="color:rgb(0,0,0);font-family:Calibri,Arial,Helvetica,sans-serif;font-size:16px;line-height:24px"><br></p><div style="color:rgb(0,0,0);font-family:Calibri,Arial,Helvetica,sans-serif;font-size:16px;line-height:24px"><strong> osg::ref_ptr<osg::Image> image_3d = createTexture3D(data,xfer_table);</strong></div><div style="color:rgb(0,0,0);font-family:Calibri,Arial,Helvetica,sans-serif;font-size:16px;line-height:24px">            </div><div style="color:rgb(0,0,0);font-family:Calibri,Arial,Helvetica,sans-serif;font-size:16px;line-height:24px"><strong>            osg::ref_ptr<osgVolume::ImageLayer> layer = new osgVolume::ImageLayer(image_3d.get());</strong></div><div style="color:rgb(0,0,0);font-family:Calibri,Arial,Helvetica,sans-serif;font-size:16px;line-height:24px">            </div><div style="color:rgb(0,0,0);font-family:Calibri,Arial,Helvetica,sans-serif;font-size:16px;line-height:24px"><strong>            tile->setLayer(layer.get());</strong></div><div style="color:rgb(0,0,0);font-family:Calibri,Arial,Helvetica,sans-serif;font-size:16px;line-height:24px">                        </div><div style="color:rgb(0,0,0);font-family:Calibri,Arial,Helvetica,sans-serif;font-size:16px;line-height:24px"><strong>            osgVolume::SwitchProperty* sp = new osgVolume::SwitchProperty;</strong></div><div style="color:rgb(0,0,0);font-family:Calibri,Arial,Helvetica,sans-serif;font-size:16px;line-height:24px"><strong>            sp->setActiveProperty(0);</strong></div><div style="color:rgb(0,0,0);font-family:Calibri,Arial,Helvetica,sans-serif;font-size:16px;line-height:24px">            </div><div style="color:rgb(0,0,0);font-family:Calibri,Arial,Helvetica,sans-serif;font-size:16px;line-height:24px"><strong>            osg::TransferFunction1D::ColorMap colorMap;</strong></div><div style="color:rgb(0,0,0);font-family:Calibri,Arial,Helvetica,sans-serif;font-size:16px;line-height:24px"><strong>            for (size_t r = 0; r < 256; ++r){</strong></div><div style="color:rgb(0,0,0);font-family:Calibri,Arial,Helvetica,sans-serif;font-size:16px;line-height:24px"><strong>                size_t rowOffset = r*4;</strong></div><div style="color:rgb(0,0,0);font-family:Calibri,Arial,Helvetica,sans-serif;font-size:16px;line-height:24px"><strong>                float red = static_cast<float>(xfer_table[rowOffset])/255.0;</strong></div><div style="color:rgb(0,0,0);font-family:Calibri,Arial,Helvetica,sans-serif;font-size:16px;line-height:24px"><strong>                float green = static_cast<float>(xfer_table[rowOffset+1])/255.0;</strong></div><div style="color:rgb(0,0,0);font-family:Calibri,Arial,Helvetica,sans-serif;font-size:16px;line-height:24px"><strong>                float blue = static_cast<float>(xfer_table[rowOffset+2])/255.0;</strong></div><div style="color:rgb(0,0,0);font-family:Calibri,Arial,Helvetica,sans-serif;font-size:16px;line-height:24px"><strong>                float alpha = static_cast<float>(xfer_table[rowOffset+3])/255.0;</strong></div><div style="color:rgb(0,0,0);font-family:Calibri,Arial,Helvetica,sans-serif;font-size:16px;line-height:24px"><strong>                colorMap[r] = osg::Vec4(red,green,blue,alpha);</strong></div><div style="color:rgb(0,0,0);font-family:Calibri,Arial,Helvetica,sans-serif;font-size:16px;line-height:24px"><strong>            }</strong></div><div style="color:rgb(0,0,0);font-family:Calibri,Arial,Helvetica,sans-serif;font-size:16px;line-height:24px"><br></div><div style="color:rgb(0,0,0);font-family:Calibri,Arial,Helvetica,sans-serif;font-size:16px;line-height:24px"><strong>            osg::ref_ptr<osg::TransferFunction1D> transferFunction = new osg::TransferFunction1D;</strong></div><div style="color:rgb(0,0,0);font-family:Calibri,Arial,Helvetica,sans-serif;font-size:16px;line-height:24px"><strong>            transferFunction->assign(colorMap);</strong></div><div style="color:rgb(0,0,0);font-family:Calibri,Arial,Helvetica,sans-serif;font-size:16px;line-height:24px">            </div><div style="color:rgb(0,0,0);font-family:Calibri,Arial,Helvetica,sans-serif;font-size:16px;line-height:24px"><strong>            float alphaFunc=0.02f;</strong></div><div style="color:rgb(0,0,0);font-family:Calibri,Arial,Helvetica,sans-serif;font-size:16px;line-height:24px"><strong>            float sampleDensityWhenMoving = 0.02;</strong></div><div style="color:rgb(0,0,0);font-family:Calibri,Arial,Helvetica,sans-serif;font-size:16px;line-height:24px"><strong>            osgVolume::AlphaFuncProperty* ap = new osgVolume::AlphaFuncProperty(alphaFunc);</strong></div><div style="color:rgb(0,0,0);font-family:Calibri,Arial,Helvetica,sans-serif;font-size:16px;line-height:24px"><strong>            osgVolume::SampleDensityProperty* sd = new osgVolume::SampleDensityProperty(0.005);</strong></div><div style="color:rgb(0,0,0);font-family:Calibri,Arial,Helvetica,sans-serif;font-size:16px;line-height:24px"><strong>            osgVolume::SampleDensityWhenMovingProperty* sdwm = sampleDensityWhenMoving!=0.0 ? new osgVolume::SampleDensityWhenMovingProperty(sampleDensityWhenMoving) : 0;</strong></div><div style="color:rgb(0,0,0);font-family:Calibri,Arial,Helvetica,sans-serif;font-size:16px;line-height:24px"><strong>            osgVolume::TransparencyProperty* tp = new osgVolume::TransparencyProperty(1.0);</strong></div><div style="color:rgb(0,0,0);font-family:Calibri,Arial,Helvetica,sans-serif;font-size:16px;line-height:24px"><strong>            osgVolume::TransferFunctionProperty* tfp = transferFunction.valid() ? new osgVolume::TransferFunctionProperty(transferFunction.get()) : 0;</strong></div><div style="color:rgb(0,0,0);font-family:Calibri,Arial,Helvetica,sans-serif;font-size:16px;line-height:24px">            </div><div style="color:rgb(0,0,0);font-family:Calibri,Arial,Helvetica,sans-serif;font-size:16px;line-height:24px"><strong>            // Standard config from osgVolume example</strong></div><div style="color:rgb(0,0,0);font-family:Calibri,Arial,Helvetica,sans-serif;font-size:16px;line-height:24px"><strong>            osgVolume::CompositeProperty* cp = new osgVolume::CompositeProperty;</strong></div><div style="color:rgb(0,0,0);font-family:Calibri,Arial,Helvetica,sans-serif;font-size:16px;line-height:24px"><strong>            cp->addProperty(ap);</strong></div><div style="color:rgb(0,0,0);font-family:Calibri,Arial,Helvetica,sans-serif;font-size:16px;line-height:24px"><strong>            cp->addProperty(sd);</strong></div><div style="color:rgb(0,0,0);font-family:Calibri,Arial,Helvetica,sans-serif;font-size:16px;line-height:24px"><strong>            cp->addProperty(tp);</strong></div><div style="color:rgb(0,0,0);font-family:Calibri,Arial,Helvetica,sans-serif;font-size:16px;line-height:24px"><strong>            if (sdwm) cp->addProperty(sdwm);</strong></div><div style="color:rgb(0,0,0);font-family:Calibri,Arial,Helvetica,sans-serif;font-size:16px;line-height:24px"><strong>            // if (tfp) cp->addProperty(tfp);</strong></div><div style="color:rgb(0,0,0);font-family:Calibri,Arial,Helvetica,sans-serif;font-size:16px;line-height:24px">            </div><div style="color:rgb(0,0,0);font-family:Calibri,Arial,Helvetica,sans-serif;font-size:16px;line-height:24px"><strong>            sp->addProperty(cp);</strong></div><div style="color:rgb(0,0,0);font-family:Calibri,Arial,Helvetica,sans-serif;font-size:16px;line-height:24px"><strong>            sp->setActiveProperty(0); // For now, always use "Standard" config</strong></div><div style="color:rgb(0,0,0);font-family:Calibri,Arial,Helvetica,sans-serif;font-size:16px;line-height:24px"><strong>            layer->addProperty(sp);</strong></div><div style="color:rgb(0,0,0);font-family:Calibri,Arial,Helvetica,sans-serif;font-size:16px;line-height:24px">  </div><div style="color:rgb(0,0,0);font-family:Calibri,Arial,Helvetica,sans-serif;font-size:16px;line-height:24px"><strong>            tile->setVolumeTechnique(new osgVolume::RayTracedTechnique());</strong></div><div style="color:rgb(0,0,0);font-family:Calibri,Arial,Helvetica,sans-serif;font-size:16px;line-height:24px"><br></div><div style="color:rgb(0,0,0);font-family:Calibri,Arial,Helvetica,sans-serif;font-size:16px;line-height:24px"><strong>            // FixedFunctionTechnique turns on GL_LIGHTING, which breaks the color rendering.</strong></div><div style="color:rgb(0,0,0);font-family:Calibri,Arial,Helvetica,sans-serif;font-size:16px;line-height:24px"><strong>            osg::StateSet* stateset = volume->getOrCreateStateSet();</strong></div><div style="color:rgb(0,0,0);font-family:Calibri,Arial,Helvetica,sans-serif;font-size:16px;line-height:24px"><strong>            // stateset->setMode(GL_LIGHTING,osg::StateAttribute::OFF | osg::StateAttribute::OVERRIDE);</strong></div><div style="color:rgb(0,0,0);font-family:Calibri,Arial,Helvetica,sans-serif;font-size:16px;line-height:24px">            </div><div style="color:rgb(0,0,0);font-family:Calibri,Arial,Helvetica,sans-serif;font-size:16px;line-height:24px"><strong>            // Our original implementation positioned the bbox [-0.5,0.5] in each dimension.</strong></div><div style="color:rgb(0,0,0);font-family:Calibri,Arial,Helvetica,sans-serif;font-size:16px;line-height:24px"><strong>            // FixedFunctionTechnique applies the locator matrix to the a unit cube [0 1] in each dimension.</strong></div><div style="color:rgb(0,0,0);font-family:Calibri,Arial,Helvetica,sans-serif;font-size:16px;line-height:24px"><strong>            // To get the equivalent spatial referencing, apply a translation of -0.5 to each dimension.</strong></div><div style="color:rgb(0,0,0);font-family:Calibri,Arial,Helvetica,sans-serif;font-size:16px;line-height:24px"><strong>            osg::ref_ptr<osg::RefMatrix> matrix = new osg::RefMatrix();</strong></div><div style="color:rgb(0,0,0);font-family:Calibri,Arial,Helvetica,sans-serif;font-size:16px;line-height:24px"><strong>            matrix->makeTranslate(-0.5,-0.5,-0.5);</strong></div><div style="color:rgb(0,0,0);font-family:Calibri,Arial,Helvetica,sans-serif;font-size:16px;line-height:24px">            </div><div style="color:rgb(0,0,0);font-family:Calibri,Arial,Helvetica,sans-serif;font-size:16px;line-height:24px"><strong>            tile->setLocator(new osgVolume::Locator(*matrix));</strong><br></div><p style="color:rgb(0,0,0);font-family:Calibri,Arial,Helvetica,sans-serif;font-size:16px;line-height:24px">I've spent the last few hours toggling settings on/off. I thought I'd see if anyone here has ideas, or how I would go about debugging why things aren't rendering correctly.<br></p><p style="color:rgb(0,0,0);font-family:Calibri,Arial,Helvetica,sans-serif;font-size:16px;line-height:24px">I also have a specific question. When working with RGBA data, should I be specifying a <strong>osgVolume::TransferFunctionProperty</strong>​, and should this property be in the float [0,1] normalized range as shown in the OSG example, or should it be in a range that matches my data? I'm a bit confused about whether/why I need to specify the transfer function when my RGBA texture already knows the color and opacity for each voxel sample.  </p><p style="color:rgb(0,0,0);font-family:Calibri,Arial,Helvetica,sans-serif;font-size:16px;line-height:24px">Sorry for the very long email. I'd appreciate any help or pointers anyone can provide.<br></p><p style="color:rgb(0,0,0);font-family:Calibri,Arial,Helvetica,sans-serif;font-size:16px;line-height:24px">Best,<br></p><p style="color:rgb(0,0,0);font-family:Calibri,Arial,Helvetica,sans-serif;font-size:16px;line-height:24px">Alex Taylor<br></p><div><br></div><p style="color:rgb(0,0,0);font-family:Calibri,Arial,Helvetica,sans-serif;font-size:16px;line-height:24px"></p></div></div></div>