[osg-users] Volume Rendering and Depth Buffer

Anna Osvin annieloveowls at gmail.com
Fri Apr 12 10:20:28 PDT 2019


Hi. In a project that I'm working on I have an osgVolume::VolumeScene containing one volume model and some polygonal models. I need to do some depth buffer checks on that scene, so I've attached depth buffer to viewer camera. When I fetch osg::Image representing depth buffer content, everything is fine, except background values are not calculated properly (they should be 1, but instead it's ~0.15). And when I add osg::Depth( osg::Depth::Function::LESS, zNear, zFar ) attribute to the camera, background values are calculated correctly, but I lose all of the polygonal models data (they are no longer visible, and not presented in depth buffer).

Here is function that does depth buffer checking:

Code:

bool pickZBufferIntersection( osgViewer::View& view, bool perspectiveProjection, const osg::Vec2& point2d, osg::Vec3& pickedPoint )
{
    osg::Camera* camera = view.getCamera();
    if ( camera == nullptr )
    {
        Q_ASSERT_X( false, "bool pickZBufferIntersection( ... )", "View has no camera." );
        return false;
    }

    const osg::Image* zImage = camera->getBufferAttachmentMap()[osg::Camera::BufferComponent::DEPTH_BUFFER]._image;
    if ( zImage == nullptr )
    {
        Q_ASSERT_X( false, "bool pickZBufferIntersection( ... )", "ZBuffer is not attached to view camera." );
        return false;
    }

    osg::Vec3f cameraPos;
    osg::Vec3f center;
    osg::Vec3f up;
    camera->getViewMatrixAsLookAt( cameraPos, center, up );

    osg::Matrixd prInv = osg::Matrixd::inverse( camera->getProjectionMatrix() );
    osg::Matrixd viewInv = osg::Matrixd::inverse( camera->getViewMatrix() );

    const osg::Viewport* viewPort = camera->getViewport();
    
    int x = point2d.x() - viewPort->x();
    int y = point2d.y() - viewPort->y();
    
    osg::Vec3 s(0, 0, -1);
    s[0] = (point2d[0] / viewPort->width()) * 2.0 - 1.0;
    s[1] = (point2d[1] / viewPort->height()) * 2.0 - 1.0;
    s = s * prInv * viewInv;
    
    osg::Vec3d v = s - cameraPos;

    double zNear = 1.0f;
    double zFar = 10000.0f;

    static uint pickNumber = 0;

    double zV, z_n, z;
    osg::Vec3f point;

    zV = ( (float*)zImage->data( x, y ) )[ 0 ];

    if( perspectiveProjection )
    {
        z_n = 2.0*zV - 1.0;
        z = 2.0 * zNear * zFar / ( zFar + zNear - z_n * ( zFar - zNear ) );

        point = cameraPos + v*z;
    }
    else
    {
        z = ( zFar - zNear )*zV;
        point = s + ( center - cameraPos )*z;
    }
    
    if( z > zNear + 1e-8 && z < zFar - 1 - 1e-8 )
    {
        pickedPoint = point;
        return true;
    }
    return false;
}




And here is viewer setup bit:

Code:

QWidget* createViewWidget(osgQt::GraphicsWindowQt* gw, osgVolume::VolumeScene& scene)
{
    osgViewer::View* view = new osgViewer::View;
    /* ... */
    osg::Camera* camera = view->getCamera();
    camera->setGraphicsContext(gw);
    camera->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR);

    const osg::GraphicsContext::Traits* traits = gw->getTraits();
    camera->setClearColor(osgColor( SCENE3D_BACKGROUND_COLOR ));
    camera->setViewport(new osg::Viewport(0, 0, traits->width, traits->height));

    osg::ref_ptr<osg::Image> zImage = new osg::Image();
    zImage->allocateImage(1000, 1000, 1, GL_DEPTH_COMPONENT, GL_FLOAT);
    camera->attach(osg::Camera::DEPTH_BUFFER, zImage);
    
    const int orthoRange = 120;
    const float zNear = 1.0f;
    const float zFar = 10000.0f;
    camera->setProjectionMatrixAsOrtho(-orthoRange, orthoRange, -orthoRange, orthoRange, zNear, zFar);
    //camera->getOrCreateStateSet()->setAttribute( new osg::Depth( osg::Depth::Function::LESS, zNear, zFar ), osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE );

    /* ... */

    view->setSceneData(&scene);
    view->addEventHandler(new osgViewer::StatsHandler);
    
    gw->setTouchEventsEnabled(true);

    return gw->getGLWidget();
}




... 

Thank you!

Cheers,
Annie[/img]

------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=75829#75829




Attachments: 
http://forum.openscenegraph.org//files/depth_buffer_depthrange_185.png
http://forum.openscenegraph.org//files/depth_buffer_154.png




More information about the osg-users mailing list