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 _______________________________________________ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org