[osg-users] Reusing depth buffer for render targets
Hi, I'm trying to reuse a depth buffer for rendering two different passes. The first one does terrain, the second one some water surface (to another output buffer, but that's not the issue here) Based on posts from the forum I though I had it figured out but it doesn't work well. Depending on how I move the camera in my application, it either looks like the depth buffer was not used at all (I see water everywhere), or it works as expected, or sometimes something in between, some parts seem to be non-rendered as they should but not everywhere. I wonder if I did anything wrong, here is the code I used, any comments would be useful, thanks! Code: //set up a depth buffer to be reused in two cameras osg::Texture2D* depthBuffer; depthBuffer = new osg::Texture2D; depthBuffer-setTextureSize(screenWidth, screenHeight); depthBuffer-setInternalFormat(GL_DEPTH_COMPONENT32); depthBuffer-setSourceFormat(GL_DEPTH_COMPONENT); depthBuffer-setSourceType(GL_FLOAT); //set up the world (scene) camera osg::ref_ptrosg::Camera worldCamera = new osg::Camera(); worldCamera-setViewport(new osg::Viewport(0,0,screenWidth,screenHeight)); worldCamera-setProjectionMatrixAsPerspective(30.0, 16.f/9.f, 0.5, 1); worldCamera-setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //camera-setClearColor(fog-getFogColor()); worldCamera-setClearColor(osg::Vec4(0,0,0,0)); worldCamera-setReferenceFrame(osg::Transform::ABSOLUTE_RF); worldCamera-setRenderOrder(osg::Camera::PRE_RENDER,0); worldCamera-setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT); worldCamera-addChild(worldNode); //add the world to the world camera worldCamera-attach(osg::Camera::BufferComponent(osg::Camera::COLOR_BUFFER0), colorsRect); worldCamera-attach(osg::Camera::BufferComponent(osg::Camera::COLOR_BUFFER1), normalsRect); worldCamera-attach(osg::Camera::BufferComponent(osg::Camera::COLOR_BUFFER2), positionsRect); worldCamera-attach(osg::Camera::DEPTH_BUFFER, depthBuffer); //set up the water surface camera osg::ref_ptrosg::Camera waterCamera = new osg::Camera(); waterCamera-setViewport(new osg::Viewport(0,0,screenWidth,screenHeight)); waterCamera-setProjectionMatrixAsPerspective(30.0, 16.f/9.f, 0.5, 1); waterCamera-setClearMask(GL_COLOR_BUFFER_BIT); waterCamera-setClearColor(osg::Vec4(0,0,0,0)); waterCamera-setReferenceFrame(osg::Transform::ABSOLUTE_RF); waterCamera-setRenderOrder(osg::Camera::PRE_RENDER,1); waterCamera-setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT); waterCamera-addChild(waterNode); waterCamera-attach(osg::Camera::BufferComponent(osg::Camera::COLOR_BUFFER0), waterRect); waterCamera-attach(osg::Camera::DEPTH_BUFFER, depthBuffer); ... rootNode-addChild(worldCamera); rootNode-addChild(waterCamera); Thank you! Cheers, Bram -- Read this topic online here: http://forum.openscenegraph.org/viewtopic.php?p=57218#57218 ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
Re: [osg-users] Reusing depth buffer for render targets
Hi Bram, The water camera is not clearing the depth buffer, which means it will be performing depth tests against the depth values from the world camera. Try setting the clear mask for the water camera to the following: waterCamera-setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); Cheers, Farshid On Thu, Nov 14, 2013 at 2:09 PM, Bram Vaessen bram.vaes...@gmail.comwrote: Hi, I'm trying to reuse a depth buffer for rendering two different passes. The first one does terrain, the second one some water surface (to another output buffer, but that's not the issue here) Based on posts from the forum I though I had it figured out but it doesn't work well. Depending on how I move the camera in my application, it either looks like the depth buffer was not used at all (I see water everywhere), or it works as expected, or sometimes something in between, some parts seem to be non-rendered as they should but not everywhere. I wonder if I did anything wrong, here is the code I used, any comments would be useful, thanks! Code: //set up a depth buffer to be reused in two cameras osg::Texture2D* depthBuffer; depthBuffer = new osg::Texture2D; depthBuffer-setTextureSize(screenWidth, screenHeight); depthBuffer-setInternalFormat(GL_DEPTH_COMPONENT32); depthBuffer-setSourceFormat(GL_DEPTH_COMPONENT); depthBuffer-setSourceType(GL_FLOAT); //set up the world (scene) camera osg::ref_ptrosg::Camera worldCamera = new osg::Camera(); worldCamera-setViewport(new osg::Viewport(0,0,screenWidth,screenHeight)); worldCamera-setProjectionMatrixAsPerspective(30.0, 16.f/9.f, 0.5, 1); worldCamera-setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //camera-setClearColor(fog-getFogColor()); worldCamera-setClearColor(osg::Vec4(0,0,0,0)); worldCamera-setReferenceFrame(osg::Transform::ABSOLUTE_RF); worldCamera-setRenderOrder(osg::Camera::PRE_RENDER,0); worldCamera-setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT); worldCamera-addChild(worldNode); //add the world to the world camera worldCamera-attach(osg::Camera::BufferComponent(osg::Camera::COLOR_BUFFER0), colorsRect); worldCamera-attach(osg::Camera::BufferComponent(osg::Camera::COLOR_BUFFER1), normalsRect); worldCamera-attach(osg::Camera::BufferComponent(osg::Camera::COLOR_BUFFER2), positionsRect); worldCamera-attach(osg::Camera::DEPTH_BUFFER, depthBuffer); //set up the water surface camera osg::ref_ptrosg::Camera waterCamera = new osg::Camera(); waterCamera-setViewport(new osg::Viewport(0,0,screenWidth,screenHeight)); waterCamera-setProjectionMatrixAsPerspective(30.0, 16.f/9.f, 0.5, 1); waterCamera-setClearMask(GL_COLOR_BUFFER_BIT); waterCamera-setClearColor(osg::Vec4(0,0,0,0)); waterCamera-setReferenceFrame(osg::Transform::ABSOLUTE_RF); waterCamera-setRenderOrder(osg::Camera::PRE_RENDER,1); waterCamera-setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT); waterCamera-addChild(waterNode); waterCamera-attach(osg::Camera::BufferComponent(osg::Camera::COLOR_BUFFER0), waterRect); waterCamera-attach(osg::Camera::DEPTH_BUFFER, depthBuffer); ... rootNode-addChild(worldCamera); rootNode-addChild(waterCamera); Thank you! Cheers, Bram -- Read this topic online here: http://forum.openscenegraph.org/viewtopic.php?p=57218#57218 ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
Re: [osg-users] Reusing depth buffer for render targets
Hi Bram, From my experience you should always add the depth texture as input sampler to the consecutive passes if they use it for writing. That sounds weird but solved those issues for me. Also keep in mind that all buffers should have the same resolution (i.e. as you are using sampleRect). Do you get any errors from the framebuffer setup? Hi, I'm trying to reuse a depth buffer for rendering two different passes. The first one does terrain, the second one some water surface (to another output buffer, but that's not the issue here) Based on posts from the forum I though I had it figured out but it doesn't work well. Depending on how I move the camera in my application, it either looks like the depth buffer was not used at all (I see water everywhere), or it works as expected, or sometimes something in between, some parts seem to be non-rendered as they should but not everywhere. I wonder if I did anything wrong, here is the code I used, any comments would be useful, thanks! Code: //set up a depth buffer to be reused in two cameras osg::Texture2D* depthBuffer; depthBuffer = new osg::Texture2D; depthBuffer-setTextureSize(screenWidth, screenHeight); depthBuffer-setInternalFormat(GL_DEPTH_COMPONENT32); depthBuffer-setSourceFormat(GL_DEPTH_COMPONENT); depthBuffer-setSourceType(GL_FLOAT); //set up the world (scene) camera osg::ref_ptrosg::Camera worldCamera = new osg::Camera(); worldCamera-setViewport(new osg::Viewport(0,0,screenWidth,screenHeight)); worldCamera-setProjectionMatrixAsPerspective(30.0, 16.f/9.f, 0.5, 1); worldCamera-setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //camera-setClearColor(fog-getFogColor()); worldCamera-setClearColor(osg::Vec4(0,0,0,0)); worldCamera-setReferenceFrame(osg::Transform::ABSOLUTE_RF); worldCamera-setRenderOrder(osg::Camera::PRE_RENDER,0); worldCamera-setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT); worldCamera-addChild(worldNode); //add the world to the world camera worldCamera-attach(osg::Camera::BufferComponent(osg::Camera::COLOR_BUFFER0), colorsRect); worldCamera-attach(osg::Camera::BufferComponent(osg::Camera::COLOR_BUFFER1), normalsRect); worldCamera-attach(osg::Camera::BufferComponent(osg::Camera::COLOR_BUFFER2), positionsRect); worldCamera-attach(osg::Camera::DEPTH_BUFFER, depthBuffer); //set up the water surface camera osg::ref_ptrosg::Camera waterCamera = new osg::Camera(); waterCamera-setViewport(new osg::Viewport(0,0,screenWidth,screenHeight)); waterCamera-setProjectionMatrixAsPerspective(30.0, 16.f/9.f, 0.5, 1); waterCamera-setClearMask(GL_COLOR_BUFFER_BIT); waterCamera-setClearColor(osg::Vec4(0,0,0,0)); waterCamera-setReferenceFrame(osg::Transform::ABSOLUTE_RF); waterCamera-setRenderOrder(osg::Camera::PRE_RENDER,1); waterCamera-setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT); waterCamera-addChild(waterNode); waterCamera-attach(osg::Camera::BufferComponent(osg::Camera::COLOR_BUFFER0), waterRect); waterCamera-attach(osg::Camera::DEPTH_BUFFER, depthBuffer); ... rootNode-addChild(worldCamera); rootNode-addChild(waterCamera); Thank you! Cheers, Bram -- Read this topic online here: http://forum.openscenegraph.org/viewtopic.php?p=57218#57218 ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
Re: [osg-users] Reusing depth buffer for render targets
Farshid, I should have been more clear about it, but that was actually my intention. The terrain and water are in the same world so i wanted to use the depth information from the terrain render to draw only visible portions of the water to the other buffer. Sebastian, I always get this error: Warning: detected OpenGL error 'invalid framebuffer operation' at After Renderer::compile but I got this from the very beginning of when I started on the project, when I didn't have any framebuffers or anything else for that matter, it was just always there from the first time I used OSG. I tried looking it up but nobody on the forum could help me with it, and it doesn't seem to do any harm... for the buffers and resulations, let me just paste the code here, this is how I set them up: Code: //set up fragment color raster osg::TextureRectangle* colorsRect; colorsRect = new osg::TextureRectangle; colorsRect-setTextureSize(screenWidth, screenHeight); colorsRect-setInternalFormat(GL_RGBA32F_ARB); colorsRect-setSourceFormat(GL_RGBA); colorsRect-setSourceType(GL_FLOAT); colorsRect-setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::NEAREST); colorsRect-setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::NEAREST); //set up fragement normal raster osg::TextureRectangle* normalsRect; normalsRect = new osg::TextureRectangle; normalsRect-setTextureSize(screenWidth, screenHeight); normalsRect-setInternalFormat(GL_RGBA32F_ARB); normalsRect-setSourceFormat(GL_RGBA); normalsRect-setSourceType(GL_FLOAT); normalsRect-setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::NEAREST); normalsRect-setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::NEAREST); //set up fragment coordinate raster osg::TextureRectangle* positionsRect; positionsRect = new osg::TextureRectangle; positionsRect-setTextureSize(screenWidth, screenHeight); positionsRect-setInternalFormat(GL_RGBA32F_ARB); positionsRect-setSourceFormat(GL_RGBA); positionsRect-setSourceType(GL_FLOAT); positionsRect-setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::NEAREST); positionsRect-setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::NEAREST); //set up fragment color raster 2 for water osg::TextureRectangle* waterRect; waterRect = new osg::TextureRectangle; waterRect-setTextureSize(screenWidth, screenHeight); waterRect-setInternalFormat(GL_RGBA32F_ARB); waterRect-setSourceFormat(GL_RGBA); waterRect-setSourceType(GL_FLOAT); waterRect-setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::NEAREST); waterRect-setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::NEAREST); //set up a depth buffer to be reused in two cameras osg::Texture2D* depthBuffer; depthBuffer = new osg::Texture2D; depthBuffer-setTextureSize(screenWidth, screenHeight); depthBuffer-setInternalFormat(GL_DEPTH_COMPONENT32); depthBuffer-setSourceFormat(GL_DEPTH_COMPONENT); depthBuffer-setSourceType(GL_FLOAT); add the depth texture as input sampler to the consecutive passes if they use it for writing. do you mean as a texture? I tried waterCamera-getOrCreateStateSet()-setTextureAttributeAndModes(0, depthBuffer, osg::StateAttribute::ON); but that didn't help. I was looking at it again and it looked like it was clipping when I moved the camera around, so I tried this (also for the other camera): worldCamera-setComputeNearFarMode(osg::CullSettings::ComputeNearFarMode::DO_NOT_COMPUTE_NEAR_FAR); worldCamera-setProjectionMatrixAsPerspective(30.0, 16.f/9.f, 0.1, 10); that seems to solve it! I suppose the clipping was causing it, but not sure how exactly. Would be helpful if I understood what was happening exactly, any idea? Thanks :) -- Read this topic online here: http://forum.openscenegraph.org/viewtopic.php?p=57221#57221 ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
Re: [osg-users] Reusing depth buffer for render targets
Hi Bram, Sorry, I misunderstood your question. The values in the depth buffer are normalized based on the near/far clip planes. If you are automatically computing the near/far planes, then they can end up being different for each camera, which causes the depth test for the water scene to be computed incorrectly. Disabling computing of near/far and forcing the same clip plane values should ensure proper depth testing between the two cameras. Does that make sense? Cheers, Farshid On Thu, Nov 14, 2013 at 2:50 PM, Bram Vaessen bram.vaes...@gmail.comwrote: Farshid, I should have been more clear about it, but that was actually my intention. The terrain and water are in the same world so i wanted to use the depth information from the terrain render to draw only visible portions of the water to the other buffer. Sebastian, I always get this error: Warning: detected OpenGL error 'invalid framebuffer operation' at After Renderer::compile but I got this from the very beginning of when I started on the project, when I didn't have any framebuffers or anything else for that matter, it was just always there from the first time I used OSG. I tried looking it up but nobody on the forum could help me with it, and it doesn't seem to do any harm... for the buffers and resulations, let me just paste the code here, this is how I set them up: Code: //set up fragment color raster osg::TextureRectangle* colorsRect; colorsRect = new osg::TextureRectangle; colorsRect-setTextureSize(screenWidth, screenHeight); colorsRect-setInternalFormat(GL_RGBA32F_ARB); colorsRect-setSourceFormat(GL_RGBA); colorsRect-setSourceType(GL_FLOAT); colorsRect-setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::NEAREST); colorsRect-setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::NEAREST); //set up fragement normal raster osg::TextureRectangle* normalsRect; normalsRect = new osg::TextureRectangle; normalsRect-setTextureSize(screenWidth, screenHeight); normalsRect-setInternalFormat(GL_RGBA32F_ARB); normalsRect-setSourceFormat(GL_RGBA); normalsRect-setSourceType(GL_FLOAT); normalsRect-setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::NEAREST); normalsRect-setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::NEAREST); //set up fragment coordinate raster osg::TextureRectangle* positionsRect; positionsRect = new osg::TextureRectangle; positionsRect-setTextureSize(screenWidth, screenHeight); positionsRect-setInternalFormat(GL_RGBA32F_ARB); positionsRect-setSourceFormat(GL_RGBA); positionsRect-setSourceType(GL_FLOAT); positionsRect-setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::NEAREST); positionsRect-setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::NEAREST); //set up fragment color raster 2 for water osg::TextureRectangle* waterRect; waterRect = new osg::TextureRectangle; waterRect-setTextureSize(screenWidth, screenHeight); waterRect-setInternalFormat(GL_RGBA32F_ARB); waterRect-setSourceFormat(GL_RGBA); waterRect-setSourceType(GL_FLOAT); waterRect-setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::NEAREST); waterRect-setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::NEAREST); //set up a depth buffer to be reused in two cameras osg::Texture2D* depthBuffer; depthBuffer = new osg::Texture2D; depthBuffer-setTextureSize(screenWidth, screenHeight); depthBuffer-setInternalFormat(GL_DEPTH_COMPONENT32); depthBuffer-setSourceFormat(GL_DEPTH_COMPONENT); depthBuffer-setSourceType(GL_FLOAT); add the depth texture as input sampler to the consecutive passes if they use it for writing. do you mean as a texture? I tried waterCamera-getOrCreateStateSet()-setTextureAttributeAndModes(0, depthBuffer, osg::StateAttribute::ON); but that didn't help. I was looking at it again and it looked like it was clipping when I moved the camera around, so I tried this (also for the other camera): worldCamera-setComputeNearFarMode(osg::CullSettings::ComputeNearFarMode::DO_NOT_COMPUTE_NEAR_FAR); worldCamera-setProjectionMatrixAsPerspective(30.0, 16.f/9.f, 0.1, 10); that seems to solve it! I suppose the clipping was causing it, but not sure how exactly. Would be helpful if I understood what was happening exactly, any idea? Thanks :) -- Read this topic online here: http://forum.openscenegraph.org/viewtopic.php?p=57221#57221 ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
Re: [osg-users] Reusing depth buffer for render targets
Thanks, that makes perfect sense. I didn't know it was normalized, so I just have to make sure the camera's have the same clipping planes, didn't need to increase it to 10 (my scene is much smaller than that :) The depth buffer is based on 32 bits floats right (just for my information)? -- Read this topic online here: http://forum.openscenegraph.org/viewtopic.php?p=57223#57223 ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
Re: [osg-users] Reusing depth buffer for render targets
Support for 32-bit depth buffers is driver dependent. I believe some will fallback on 24-bit if 32-bit is not supported. On Thu, Nov 14, 2013 at 3:49 PM, Bram Vaessen bram.vaes...@gmail.comwrote: Thanks, that makes perfect sense. I didn't know it was normalized, so I just have to make sure the camera's have the same clipping planes, didn't need to increase it to 10 (my scene is much smaller than that :) The depth buffer is based on 32 bits floats right (just for my information)? -- Read this topic online here: http://forum.openscenegraph.org/viewtopic.php?p=57223#57223 ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org