[Resending because the copy I sent from GMail earlier hasn't shown up... 
Apologies if it
does and dupes. ]



Paul Martz and I have discussed this this afternoon, and I think that
I'm pursuing a dead end with this technique, but I thought I'd throw
it out there in case anyone sees an easy hack for it before I throw it
out and try the more complex option.

The scene:
Two pieces of geometry in the scene, objects A and B. Both are 3D and
need z-buffering in order to render properly.

The Goal: Render both of them, but with object A _always_ obscured by
object B, regardless of what their Z values (which are mostly
coincident) would normally dictate.

The Constraints:
I'd rather avoid Render To Texture and tricks like that if possible.
I'd like this to be a technique that I can store in a .osg file and
have work self-contained (so it can be moved between computers with
various different versions of OSG 2.8+).

The Theory:
So, my aim was to clear the RGBZ buffers, render object A (with normal
Z test), then clear just the Z buffer and render object B (also with
normal Z test), resulting in B always overwriting A's pixels. It's
pretty simple in basic OpenGL. But structuring a .OSG file to recreate
this effect seems tricky.

The Technique:
I figured maybe I could get away with putting A into the root of the
Scene Graph, and B underneath a ClearNode with only Z clear enabled
and with its StateSet's RenderBin set to render later. ClearNode and
StateSet both are well represented in a .OSG file.

The Code: (insert in place of viewer.setSceneData() in osgviewer.cpp
for testing)

{ // test code
   osg::ref_ptr<osg::Group> magicZGroup = new osg::Group;
   osg::ref_ptr<osg::Node> ObjectA = osgDB::readNodeFile("ObjectA.osg");
   osg::ref_ptr<osg::Node> ObjectB = osgDB::readNodeFile("ObjectB.osg");
   osg::ref_ptr<osg::ClearNode> magicZClear = new osg::ClearNode;

   // This RenderBin number (1) must be later than default (0, which
ObjectA currently uses)
   // (or change RenderBin of ObjectA to be earlier than default:0)
   // set ClearNode's StateSet to utilize this RenderBin
    magicZClear->getOrCreateStateSet()->setRenderBinDetails(1,"RenderBin");

   // this clears the Z buffer before drawing children of this group
   magicZClear->setClearMask(GL_DEPTH_BUFFER_BIT);

   magicZGroup->addChild(ObjectA.get());
   magicZGroup->addChild(magicZClear.get());
   magicZClear->addChild(ObjectB.get());

   viewer.setSceneData( magicZGroup.get());
   } // end test code

The Problem:
Besides the fact it gives trippy trails (because nobody ever clears
undrawn parts of the screen), it looks like the Z-Clear operation is
actually done at the beginning of the Scene draw, not at the start of
drawing the children of the ClearNode. So, the ClearNode children
inherit a z-buffer that still has ObjectA's Z values in it.

Paul told me it wouldn't work (you can now say "I told you so!"), but
I wanted to try it because it's cleaner than the obvious alternative,
which is to use RenderStages (which have clearing capability built
into them). Paul suggested using multiple Camera objects in the Scene
and playing with the heirarchy, reference frame and identity matrix to
make a sub-camera track its parent. I am going to dive into this and
try it next, but I figured I'd see if ClearNode was clearly out first.

Interested in any feedback about the ClearNode tactic, or the
RenderStage/Camera alternative. I'll summarize whatever I find to
work.
-- 
Chris 'Xenon' Hanson, omo sanza lettere                  Xenon AlphaPixel.com
PixelSense Landsat processing now available! http://www.alphapixel.com/demos/
"There is no Truth. There is only Perception. To Perceive is to Exist." - Xen
_______________________________________________
osg-users mailing list
osg-users@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to