PDA

View Full Version : Drawing infinite shadow volumes confusion

Oliver LS
12-12-2002, 09:01 PM
I have been studying the nvidia papers and code on robust infinite shadow volumes using zfail stencil. The stencil isn't quite the issue yet, there are a couple of things here that have gotten me a bit lost. I would appreciate any input on this.

In this example code, for the drawing of the caps and the poss shil edges, they begin by doing this:

vec4f olight;
matrix4f ml = object[mindex].get_inverse_transform() * light.get_transform();
ml.mult_matrix_vec(light_position, olight);

This 'object' and 'light' seem to be of strange types, and I can't quite track down what they are doing in these .get_*_transform() calls. I understand of course object is the shadowcasting mesh, and light is the light source. As best as I can understand now, they are just getting the matricies used to transform these objects into world coordinates? This does not seem right though, as the next line is to multiply that by (what i assume) the light's position? What they are doing here is obviously key to the ideas, as their drawing looks like such:

if(facing_light) // draw locally
glVertex4f(pn.x, pn.y, pn.z, 1);
else // draw at infinity
glVertex4f(pn.x*olight[3] - olight[0],
pn.y*olight[3] - olight[1],
pn.z*olight[3] - olight[2],
0);

So the real question is, what is olight, how and why is this derived, and why is it required to draw these caps at infinity?

The second question I have is strongly related, the way I understand the vertex4f(x,y,z,w) calls, it works out as x/w y/w z/w. How is division by zero allowed? I am not familiar with this at all, my only intuition says that opengl somehow works this out as a limit; but that leads me to believe that these verticies would be interpreted as +/- INF, which does not make sense with how these caps are drawn.

I appreciate in advance any time somebody could spend explaining this, and I apologize for posting this in the advanced forum; but I had serious doubts that I would receive much help with this topic in the newbie one.

.oliver.

SirKnight
12-14-2002, 08:43 AM
Alright let me explain olight. olight is the object-space light. The transformations go like this:

Object-Space->[MODEL MATRIX]->World-Space->[VIEW MATRIX]->Eye-Space->[PROJECTION MATRIX]->Clip-Space->etc...

Ok opengl ofcourse combines the model and view matrix to make the modelview matrix. This doesn't help us in this case. Now your light is in world-space. So to get it into obect space you need to transform it by the inverse model matrix. The variable 'object' contains the moddeling transforms that is applied to the model, in this demo's case the knight model. So like I said earlier we need the inverse model matrix so the .get_inverse_transform() does just that. Now that needs to be multiplied the the modeling transforms of the light, because you may want to rotate/translate the light around or something and if this multiply didn't happen then the transforms you're applying to the light would never happen. So now we take this inverse matrix and multiply it with the light position to get the object space light position. Which is what you need. Search through nvidia's code to find how they do the get_*_transform functions if you want to see exactly how they handle it. All they are doing is just simple glRotate's and glTranslate's. Since the computation of the shadow volumes occurs in object space, this is why we need the light in object space. It wouldn't make sence to do math with things that are in two different spaces.

I don't know exactly how opengl takes care of the w = 0 thing but I do know that opengl is required to handle it correctly. What happens when w = 0 is that the point you specify now turns into a vector; just a direction. When it's a 1 its a point in 3d space somewhere. So since it's just a vector, it will project that part of the polygon (the vertex which has its w coord 0) in the direction of this vector.

-SirKnight