Jump to content
  • Advertisement
Sign in to follow this  
genesys

Stencil Shadows - please help me..

This topic is 4255 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi! i implemented stencil shadows in my little engine and they're finaly working... now i have two problems: 1.) it's slooooooooow! :( my process is the following: on startup, i store for every edge of a triangle its neighbour triangles on runtime, i do in every frame (since the light source is moving): -step1: loop through all faces and calculate, wether they are lit by the lightsource -step2: loop through all lit faces { loop through all three edges of the current lit face { if there is no neighbourface or the neighbourface isn't lit{ take the two vertices of the edge and calculate two more vertices by adding the lightvector to these two points; store all four points as quad in a list;}}} -step3: loop throug all quads and draw them to the stencil buffer (incr) using glBegin(GL_QUADS) and cull_face set to GL_BACK -step4: loop again through all quads and draw them to the stencil buffer (decr) using glBegin(GL_QUADS) and cull_face set to GL_FRONT -step5: draw a big black quad to the screen using the stencilbuffer as mask ... this i do in every frame . . . it's really slow - i'm already using shadow LOD (each shadow LOD model has between 30 and 50 triangles) is there anything i can improve or do differently to improve the performance?? result: http://neo.cycovery.com/stencil_problem1.gif 2.) the shadow shape is visible at this place, where the shadow volumes end: http://neo.cycovery.com/stencil_problem2.gif i understand why this effect appears, but i don't really know, what i could do against it (without decreasing the performance even more...) If somebody could help me on that or give me some hints, i'd really appreciate it! thanks a lot! [Edited by - genesys on November 27, 2006 12:46:47 PM]

Share this post


Link to post
Share on other sites
Advertisement
i'm not sure if this is the answer your looking for but you could cap your shadow volume to get rid of those floating artifacts below the whole city.

Share this post


Link to post
Share on other sites
Quote:
2.)
the shadow shape is visible at this place, where the shadow volumes end:
http://neo.cycovery.com/stencil_problem2.gif
i understand why this effect appears, but i don't really know, what i could do against it (without decreasing the performance even more...)


Just a shot in the dark here, but couldn't you just clip the shadow ends out down there? It looks like they're being rendered far below your map...

Share this post


Link to post
Share on other sites
by caping you mean to trace for every quad the distance to the next object in lightvector direction and use this distance to calculate the length of the quad?

i'm afraid that this decreases my performance even more . . .

Share this post


Link to post
Share on other sites
Quote:

by caping you mean to trace for every quad the distance to the next object in lightvector direction and use this distance to calculate the length of the quad?


whooooa, that sentence just blew my mind....

take a look at this page:
http://www.codesampler.com/oglsrc/oglsrc_8.htm#ogl_shadow_volume

maybe youve already been there, maybe not, itll probably give you some insight anyways

Share this post


Link to post
Share on other sites
thanks for the link - but this sample is way too basic . . . my stencil shadows work - they'r just terribly slow :(

would it maybe make sense to use Vertex Arrays for the shadow volume? the vertices have to be calculated in every frame again and the count of vertices can change from frame to frame, that's why i think vertex arrays won't help me here. the same thing for display lists... since the shadow volume changes in every frame i'd have to compile the display list once per frame - i don't think this would increase the performance although i have to draw the shadowvolume twice per frame and could call the compiled displaylist when drawing it the secound time . . . or do you think a display list would help me?

Share this post


Link to post
Share on other sites
maybe the answer is actually in your question...

it's slow.....why could it be slow?

judging by your second image the lightsource appears to be the sun.
you say "the light source is moving".....but shadows that the sun casts dont typically move noticeably all the time. Maybe you should do all these "COMPLEX" calculations once every 1000 frames or maybe 10,000 frames.

...

Another possible solution would be to consider another method besides shadow volumes to create shadows for buildings and other static objects. I doubt that commercial games with big citys employ a method like the one your using to shadow TONS of buildings in a city.



not trying to bash your idea or anything because i actually think the images you posted look pretty good. i would like to hear your thoughts on my feedback too.

good luck

Share this post


Link to post
Share on other sites
Hi paulshady

The sun is moving verry fast.. 1 minute = 1 day.

You are right, that an image based shadow approach will create faster results and maybe is more clever for a big city...

But i'm writing an engine and this city is only one application for it - i want to make it able to serve for different needs, so i want to implement stencil shadows as performant as possible. That's why i'm asking...

at the moment it's running at 15 frames... i think one big problem is, that i have to send single GL_QUADS calls to openGL... maybe an idea how i could achieve it with less calls?

Share this post


Link to post
Share on other sites
Quote:
i think one big problem is, that i have to send single GL_QUADS calls to openGL... maybe an idea how i could achieve it with less calls?


You're not using immediate rendering are you? That would be pure evil.

Either way, you might find it faster to batch up your geometry into a single buffer, and then push that buffer as a quad vertex-array in a single shot when its full, or when you are finished. This way you wont be sending individual quads, but instead a single stream of data which the GPU will be able to consume much quicker.

Share this post


Link to post
Share on other sites
ive done something like this before:

struct VERTEX_BUFFER
{
VECTOR3 position; //VECTOR3 is 3 floats
} * VertexBuffer;

For shadow volumes i think youll probably only need the position, otherwise you can fill up your struct with whatever else you want (UV Coords, Normals, etc...)

Anyways, put your entire list of shadow volume data in the VERTEX_BUFFER thingy.

Once you do that OGL allows this:

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


I definitely prefer these calls over the GlBegin() glEnd() stuff.
Let me know if youve used them before. also please don't correct my OGL syntax, i realize it might not be entirely accurate because i mainly use DirectX.


Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!