[ODE] Using rays to generate a light/shadow map
shamyl at zakariya.net
Wed Nov 3 09:14:43 MST 2004
I've got a terrain system managed by ODE as a trimesh with great
success. Further, I use ray intersections with the trimesh for
height-for-point calculations ( to keep the camera above ground ) and
for laser beam intersections. All this works *beautifully*.
I mention this because I consider myself to be reasonably proficient
now with rays and trimeshes. I've read the documentation six ways to
sunday and I thought I'd learned the quirks of ray intersections by
this point. Of course, I readily admit I may have missed something.
Anyway, I recently thought, why don't I add static shadows to my
terrain? I've already got a lightmap which uses surface normals and
height factors to determine final color, so having static shadows would
just be a matter of casting a ray from the center of each triangle to
the lightsource and determining if any part of the terrain's geom
intersects that ray -- I could then use this to lighten or darken my
lightmap accordingly. Simple enough.
Well, the trouble is that it produces garbage! I know that my lightmap
is still being stretched correctly across the terrain because lighting
and color are still correct outside of the garbage shadowing.
So, printing out contact info for each collision I get, apparently,
contact points just a smidge above ray origin. E.g., if my ray is
emitted from 0,0,0 and the surface normal of that triangle is 0,0,1 and
the normalized vector to the lightsource is 0,0,1, I'll get a contact
point like 0,0,0.46.
Here are some real numbers, randomly selected from a dump of about
30,000 erroneous contacts:
surface( 791.01, 4990.24, 0.57 ) <-- ray origin
normal( -0.00, 0.00, 1.00 ) <-- surface normal
toLight( 0.00, -0.04, 1.00 ) <-- vector to lightsource
contact (791.01, 4990.24, 0.59 ) <-- point of ray contact
contactDist: 0.014612 <-- distance to point of contact
For reference, I'm treating +Z as up.
Anyway, I know there's nothing for the ray to collide with. Also, I'm
projecting the ray's origin away from the triangle center along the
triangle's surface normal by 0.5 units so the ray won't collide with
the source triangle.
So, the only thing I can guess is going wrong here is this: I'm doing
this lighting calculation during the loading of a level, after the
terrain geom is created, but before calling dWorldStep -- dWorldStep
isn't called until the loading process is complete and the game playing
So, I'm thinking that even though I'm manually calling dCollide with my
ray and with the terrain geom, perhaps there's some magic that needs
doing by calling dWorldStep at least once?
Am I missing something obvious?
"this is, after all, one of those movies where people spend a great
deal of time looking at things and pointing."
From a review of _Fantastic Voyage_
More information about the ODE