Hello !
I hope you don't mind I address you directly for this question, but as you
implemented the view-dependent shadow techniques, you are best placed to
answer it.
Well... we will see if I will be able to help here.
I am currently investigating a problem that seems to be caused by the
ordering of RTT passes. I have a scene that uses osgOcean and osgShadow,
and the shadow INSIDE the refraction (which is an RTT effect) is late
compared to the shadows OUTSIDE the refraction (i.e. above the water
level). What I mean by late is that the shadow moves away from the casting
object if I move the eye around, but stops moving and is in the right
place as soon as I stop moving the eye. So the refraction pass seems to be
happening before the shadow pass.
I understand. I know this problem well from my experience.
The nodes are ordered like this:
root
ShadowedScene
OceanScene
<the scene>
And in the OceanScene traverse() method, there is a check if the current
camera is the shadow pass camera or analysis camera (for DrawBounds
techniques) and just do a regular traversal in that case. My expectation
was that the first traversal of the OceanScene would be the shadow pass,
then the main pass, and so when we do the refraction RTT (during the main
pass), the shadow map would already be correct for the current frame.
[..] So the main pass is done (culled) before the shadow pass. I can
understand that the bounds calculation needs to cull the shadow receiving
scene first, or else we won't know where the shadow map should lie.
However, I wonder how this even works.
Culling order does not need to be the same as Rendering order. Rendering
order is defined by PRE_RENDER / POST_RENDER / NESTED_RENDER camera flag.
Cull visitor on the other hand simply traverses the scene tree in first
encountered/first processed order.
My understanding is that when the cull visitor traverses a scene graph, it
accumulates the drawables and state into a list. It does this in the order
it visits notes, and might reorder based on state or other criteria
(distance to camera for the transparent bin, for example).
Sorting is done in Draw stage as far as I know.
So given the code above, how does the cullShadowCastingScene() manage to
place the drawables for the shadow pass before the ones for the main pass,
even though the cullShadowReceivingScene() (culling the main pass) is
before?
Each camera has render order flag and associated RenderStage+RenderBin set.
Cull visitor simply fills these render stage bins and state graphs without
checking which will be rendered first. They are waiting for Draw phase to be
rendered and they are then drawn in order defined by cameras. Main question
here I believe is how to ensure that PRE_RENDER cameras will render in
certain desired order. And honestly I don't know definite answer to this
question. My tests with analysis & shadow cameras seem to suggest that first
traversed by cull visitor will be rendered first. For DrawBounds method
order of culling is 1: scene / 2: analysis / 3: shadow. Scene has standard
order (i am not sure but suppose its NESTED) and analysis and shadow are
PRE_RENDER. So if analysis comes before shadow (which I made sure it does)
it means that first PRE_RENDER camera traversed by cull visitor will be
drawn first.
I think for osgOcean's refraction pass to contain correct shadows, I would
need to do something similar, i.e. place the drawables for that pass after
the shadow pass, but before the main pass, in the render list. I'm
actually surprised that's not what happens already, since the sequence
should be:
cullShadowReceivingScene()
--> eventually calls OceanScene::traverse()
--> does cull for refraction RTT camera
--> then does cull for main pass
cullShadowCastingScene()
--> does shadow pass, somehow placing results before main pass, which
for all it knows should contain the refraction pass
And the above order of cull visits explains the effect. I assume refraction
RTT camera is PRE_RENDER cam like analisys and shadow. So its rendered first
because its culled first. You would need to put refraction cull after
cullShadowCastingScene() to be sure it will get rendered at the right
moment, I guess.
Thanks in advance,
You are welcome, but I doubt I helped ;-)
Cheers,
Wojtek
_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org