Stencil Shadows - please help me..

Started by
14 comments, last by genesys 17 years, 4 months ago
I'll tell you what I do. It's not the fastest, but it's fairly quick (as in runs ok on a 1ghz pc with a geforce 2 mx). Memory usage wasn't really a problem in my case, I just tried to keep the cpu and gpu usage down.

Firstly, I used a better algorithm to generate the shadow volumes. Not really a performance thing, more of a robustness thing, but here's a paper.

Secondly, you mentiond GL_QUADS. If that's how you're constructing your shadow volumes, then that may be your problem right there. What I do is create a vertex array for twice as many vertices as my object actually has. In the first half I put the objects vertices, and in the second half I put them in extruded in the light direction. It would probably be better to work out which vertices need extruding, but I'm not sure if that would be faster or not, and memory wasn't an issue.

Next, you construct an index array for rendering your shadow volumes. I'll assume depth fail here. First thing is the front cap. Just find every triangle in the model that faces the light and add it into the index array. Then the back cap (should fix your artifacts). Add them all in again, but this time swap the winding and offset the indices so that they point to the second half of the vertex array. Finally, the hard part, the sides of the volume. Go through all the edges that need extruding, and add a couple of triangles that make up a quad between those two vertices and the corresponding vertices in the second half of the array. Make sure the winding is such that they face "outwards".

Finally, we can draw the shadow in just two calls, once to draw front faces and once to draw backfaces. Your graphics card will thank you.

If you're actually fillrate limited, then that's a bit trickier. See if you can reliably get the shadow volumes to only go just through the ground. If you have a ground plane that's always at the same height that shouldn't be tooo hard. Also, make sure your volumes are actually optimal, and you're not treating every edge as an extruded edge or something.
___________________________________________________David OlsenIf I've helped you, please vote for PigeonGrape!
Advertisement
Thanks a lot for all your suggestions!!

@Exorcist: yes - at the moment i'm using emmediate rendering - that's why i told that it meight be a problem. I just was afraid that building a vertex array in every frame would be more consuming than sending each quad. but it seems that i was wrong! So your suggestion is, that i build the vertex array in every frame and then send it (somehow - i have to learn how first) to openGL? this leads me to another (for me) important question: For my static objects (buildings) i use display lists. When i compile them, i use immediate render calls (glBegin-glEnd) between glNewList(name, GL_COMPILE) - glEndList. Would it make sense here too to create a vertex array within this glNewList-glEndList call?

@paulshady: Till now i tried to avoid Vertex Buffer Objects because i heard that they are verry hardware dependant - and my job is to make an engine which is cross-platform and works on as many computers as possible... one limitation is, that i shouldn't go beyond openGL 1.5.. i think VBO's are part of 1.5 - so do you think my doubts are without any reasons? if it's really no problem and VBO's will do the trick then i'll stick to them...

@RAZORUNREAL: aaaah! now i understand what 'capping' is :) thanks a lot for this article! do you also think that it would be best to build a vertex array
Just forget using vertex arrays in display lists, read a tutorial for both, their differences & their uses, & you will see why..You're better off using VBOs for static objects, as long you don't have enormous amounts of data! Also nvidia has a very nice tutorial about stencil shadows & reflection, check(google) it out!!
I don't think that VBOs help me at all, since the vertex data changes in every frame (not only position, also count) so I have to upload it to VRAM again and then it's speed is the same (or maybe even less?) as with vertex arrays . . .
genesys - you mention that you don't want to use VBO's....I could be wrong, but i don't think these calls use Vertex Buffer Objects

glInterleavedArrays( GL_V3F, 0, myMesh.VertexBuffer );
glDrawElements( GL_TRIANGLES, listSize, GL_UNSIGNED_INT, &VertexBuffer );


you should prefer calls like these over sending hundreds of vertex3f calls over and over anyways.....i think that style is just for really new opengl users.....again, i could wrong
paulshady:

yes - i do it that way now . . . at least i think so - i'm using glVertexPointer instead of glinterleavedarrays and then i use glDrawArrays - and the performance is better now . . .
thanks!

This topic is closed to new replies.

Advertisement