Possible error in shadow volume paper

I was looking through the new shadow volume paper this morning and i noticed something that didnt look right. At the part where it shows some code that puts all the values into a matrix for the Pinf matrix is not correct. For example; the code part that says: Pinf[3][2] = -2near. That is not right b/c if you look at row 3 (the fourth row) and column 2 (3rd column) in the previous page in the Pinf matrix you will see that [3][2] is actually -1. Another example is where they say: Pinf[2][3] = -1. If you go back and look at the Pinf on previous page [2][3] actually has -2near.

There are many more mistakes like this i dont want to list them all. This was kinda confusing b/c i know that in C/C++ in 2dim arrays you access them by [row][column] and knowing this, this does not follow what was done in this paper. I know that opengl matrices are ordered differently than how C organizes arrays in memory but in this case that doesnt matter.

Oh, BTW, kinda getting off my subject here but i have been searching around google and opengl.org and i cant seem to find anything that says why for example in Pinf[0][0] they use cot(fov)/aspect. [0][0] in the regular proj matrix is (2*near)/(r-l). I cant seem to figure out why that is cot(fov)/aspect. Ya that not may be very advanced but its bugging me. I just cant find anything that talks about that.

-SirKnight

There are correct. Remember that opengl is COLUMN major.

so p[3][2] is 4th column, 3rd row.

For your 2nd question, I believe it is a typo. They mean atan.

cotangent = 1 / tan x

Well it is actually a fight between different language( mainly french and english ).

But, anyway if you knew they meant atan, then they are simply using the gluPerspective( where you pass a field of view and the aspect of the screen) interface instead of glFrustum interface( where you give, right, left, top, bottom ).

[This message has been edited by Gorg (edited 03-25-2002).]

Oh silly me. I see what i was doing. I was looking at the printout of how the matrix looks on that page and trying to convert it straight into C code as it is shown. I just figured that how they had the matrix typed out was setup as how C makes 2dim arrays. But even if i put all of that into a 2dim array the ‘C way’ all i would have to do is do a transpose so opengl would like it.

O well, simple mistake.

Now that, that is out of the way i see something else in here that is wierd. The parts of the matrix that says:
(R+L)/(R-L) and (T+B)/(T-B) is assigned a 0 in the c code on page 5. Which is Pinf[2][0] and Pinf[2][1] (in opengl’s column major form). Why is this like that?

-SirKnight

I said a load of crap in my earlier post :

Their cotangent is 1/tan. cotangent of angle won’t help you very much !

So let’s start over :

  1. [2][0] and [2][1] are 0, because in their matrix, just like with gluPerspective, right == - left and top == -bottom.

So right + left == 0 and top + bottom == 0

  1. cotangent business, if you draw on a sheet of paper near with top and the angle theta(the angle is in the y axis that is why you use top), you will see that tan(theta) = top / near

And since we give an aspect which is the proportion of the screen, we get right*aspect = top

Now, we need to prove that

cotangent(theta) / aspect = 2 * near / ( right - left )

tan(theta) = top / near ==> cotangent(theta) = near / top
so we get :

near / top / aspect = 2 * near / ( right - left )

since right * aspect = top ==> top / aspect = right

near / right = 2 * near / ( right - left )

Great, now since right == -left, we get right - left = 2 * right

near / right = 2 * near / ( 2 * right )

And so the 2 terms are equivalent.

You can do the same proof for [1][1]

[This message has been edited by Gorg (edited 03-25-2002).]

Aaahhhhhhh. I understand now methinks. Earlier i was trying some stuff on paper but i was just confusing myself. Now i see what i was doing wrong. Thanks.

-SirKnight

Oh one more thing. Should i only use this Pinf matrix when i draw the volumes or should it be used through out the whole program? Something like this:

Draw some stuff with normal P matrix
Push P
Load Pinf
Draw shadow volumes
Pop P (now we have old regular P again)
Draw other stuff

Or will that cause some bad invariance problems?

-SirKnight

You can draw geometry with a different view matrix than the view volume, you won’t have invariance problems.

Invariance problems only occur if you want to exactly redraw the same geometry in the same spot. Obviously this is not the case with shadow volumes.

Remember that there is a loss of precision with Pinf.

Ok thats what i thought but i had a little doubt that bugged me.

-SirKnight

SirKnight,

You’ll have to use the same matrix for all your geometry ( shadow volumes or not ). If you use Pint for the volumes and Pother for the rest, you will get artifacts.

[This message has been edited by PH (edited 03-25-2002).]

Originally posted by PH:
[b]SirKnight,

You’ll have to use the same matrix for all your geometry ( shadow volumes or not ). If you use Pint for the volumes and Pother for the rest, you will get artifacts.

[This message has been edited by PH (edited 03-25-2002).][/b]

Really, what kind of artefact?

I can see cases where where some geometry is at the egde of shadow volume, it might be incorrectly inside or outside, but it will only be pixel errors, at that point it does not matter.

Hmm, ok so my first thought on that was correct for the most part. I guess thats what i get for not trying it out. Well not having time to finish the demo doesn’t help either.

-SirKnight

Just a thought, wouldnt using the Pinf for the whole program cause problems with all the other geometry if they are far away and need to be clipped? If you had for example a terrain engine, you wouldnt want to render terrain a long ways off that cant be seen. The far clip plane is good for clipping far away stuff that should be clipped. Well…maybe scissoring the scene would fix that. What are your thoughts on that?

-SirKnight

scisoring is 2d, will not help

i dont think we need far clipping for anything, i never needed to clip something if it is too far away ( i always set the far clipping plane behind )

and you cant use it, because else stuff that is drawn with normal P has different z-values in the z-buffer than stuff drawn with Pinf, and, as you know, it IS the same stuff… only one time the shadowvolumes of it and one time the geometry…

Gorg,

As Dave pointed out, you will need the z-values to match up exactly. When you create the shadow volumes, you use the occluders front facing triangles ( wrt. the light ). If you don’t use the same projection matrix for filling the depth buffer and rendering the shadow volumes, you’ll get z-fighting artifacts ( shadow leaks ) on the occluder.

Originally posted by SirKnight:
Just a thought, wouldnt using the Pinf for the whole program cause problems with all the other geometry if they are far away and need to be clipped?

For culling geometry, you can ( and should ) use a different frustum. So, if some geometry is on the outside of your virtual far plane ( the far plane you would have used, if you weren’t doing infinite shadows ), simply don’t draw it. Since you do the culling on the CPU, so you are free to use any culling methods that you need.

Ya i guess the far plane isnt needed like if i use some culling algo like BSP/PVS, portals, octtree, etc. I dont know much about terrain rendering atm but i guess it would be similar, some algo telling which parts can be seen at the current position or something.

-SirKnight

The virtual far plane you talk about sounds pretty good. In my culling algo i could just pretend there was some far plane somewhere and which ever polygon is farther than it, dont render it. Now after this discussion i have some new things to play around with.

i dont think we need far clipping for anything, i never needed to clip something if it is too far away ( i always set the far clipping plane behind )

Setting the far plane behind, now that is something i never heard of doing! I never would have thought that would work but i guess so.

-SirKnight

[This message has been edited by SirKnight (edited 03-26-2002).]