Sign in to follow this  

Real Time Shadow With Multiple lights, new tutorial

This topic is 4864 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

Here is a tutorial I wrote because a lot of people asked how to create shadow like doom3, and mostly : how to create shadow, but with multiple lights sources? Here it is : http://www.geocities.com/duktroa/RealTimeShadowTutorial.htm If the link is not working, try this mirror : http://www.angelfire.com/games5/duktroa/RealTimeShadowTutorial.htm Tell me what you think, if you would like to change something. I need feedback on this, its my first tutorial. But I want the maximum of people to be able to make stencil shadow this way, because after Doom3, this will become a new standard in the industry. ;) [Edited by - Daivuk on August 19, 2004 9:08:32 PM]

Share this post


Link to post
Share on other sites
Wow, that is a really nice tutorial. I'm going to have to read over it more closely but I think that gave me a very good idea of how shadow volume works, whereas OGL Game Programming just kind of confused me =P

I did find one spot really rough, the 1-1 thing, where the shadow gets capped... then again I'll read it over one more time and try to find out what it is that's confusing me.

Other than that, nice tutorial, the pictures especially helped =P

Share this post


Link to post
Share on other sites
Ya, I didnt explain very well why caping..
Its hard to explain lol, probably I should update it with example situations of bugs if we dont cap.

Share this post


Link to post
Share on other sites
humm. sorry, I have problem with data transfer on geocities. They said I have too much data transfer and they close the site :@
Its ok, I create the same site on angelfire if geocities not working
http://www.angelfire.com/games5/duktroa/RealTimeShadowTutorial.htm

[Edited by - Daivuk on August 19, 2004 9:51:31 PM]

Share this post


Link to post
Share on other sites
OMG! capping is fine! it makes sense! i missed the "draw the front faces" part. Wow, that's cool... wish I had an engine to just jam this into now =P

Site works fine for me too... no problems at all... though out of fear I think I will save this to my comp =P

Thanks a lot again, i really think it's a easy to understand tutorial for a shadow method that's pretty much perfect. Yay.

Share this post


Link to post
Share on other sites
Wow! I followed it very well. That having been my first exposure to Carmack's awesome shadows and how they work.

Is this the technique that ID used and Creative Labs sued over because they had patented this? Or is that something else to do with the shadows? Just what was it about the technique that Creative Labs had patented?

Share this post


Link to post
Share on other sites
For the carmack's reverse (the thing with the stencil shadow, its from carmack. There is an article about that on gamedev. Search for Carmack's Reverse) For the multi-pass technic I use to combine all the lights, I dont know if carmack made it like that, But It give the same result. There is a bunch of way to optimise it with shaders and multi-texturing.

Share this post


Link to post
Share on other sites
For models you can map the silouettes and thus make only one volume rather then many by checking on the CPU for each face in the model if it is front facing or back facing from the light's perspective. Then go through all the edges and those that lie between two faces where one faces toward the light and one away form the silouette. Then just extrude the volume using only those edges. I'm sure you can optimise this better, but anyhow.

Share this post


Link to post
Share on other sites
Ya :) Silouhette determination, I mention that in the tutorial, but its not about that, I just wanted to explain how to compute the shadow ;)

Share this post


Link to post
Share on other sites
Nice tutorial Daivuk - I skimmed through it and it seems to explain things quite well. I'll have to implement that some time..

It would have been nice with a little more on the actual creation of the shadow volume, because that's the trickiest part, I think.

One little question, about the first screenshot: If the light is in the center of the room, why is the face on the right pillar that is facing away from it lit? [grin]

Quote:
Original post by Slaru
Is this the technique that ID used and Creative Labs sued over because they had patented this? Or is that something else to do with the shadows? Just what was it about the technique that Creative Labs had patented?

Yes, that's the one - "Carmack's reverse." The patent has been discussed quite a lot, so I won't say anything more about it here. Do a search, or look here (for example) if you want to find out more.

Share this post


Link to post
Share on other sites
Quote:
One little question, about the first screenshot: If the light is in the center of the room, why is the face on the right pillar that is facing away from it lit?

Thats because I forgot to make the test : If the face is facing the light. So All the faces receive lighting. With the shadow hidding it, thats dont make any difference, but I'm computing lighting here for nothing, so : Thank to show me up! lol, I will increase my frame rate. :P

Share this post


Link to post
Share on other sites
Quote:
How about some source, or a demo?

I put some sources at the end of the tutorial, more about what opengl functions to call in what order.
That can be a good idea to put the little demo I made for this tutorial (but not the source, its about 23 classes, that will not help).

Share this post


Link to post
Share on other sites
Great tutorial, two thumbs up :).

Now have you tried your tutorial with more complex models?
I would think not since using that code along with a more tesselated mesh with a lot of round areas will result in a not-so pleasing visuals.

Here's how things can be improved:

First of all we render the scene to the color and depth buffer with an ambient shade/color that is independant of all light sources in the scene. We also use the models diffuse texture maps to enhance the attenuation when all rendering passes are completed.


//Start ambient pass
activateNTextures(&sceneGroupParent, 1);
glPushAttrib(GL_ENABLE_BIT);
glColor3f(0.1f, 0.1f, 0.1f);
triangleCount +=sceneGroupParent.render(RENDER_TEXTURES |ENABLE_FRUSTUM_CULLING);
glPopAttrib();
glColor3f(1,1,1);
activateNTextures(&sceneGroupParent, MAX_TEXTURE_UNITS);
//End ambient pass





Then we do everything you described in your shadowing passes with textures on as well as all the shaders/special effects, but definitely NO ambient since we already made use of it in the first pass.
We can also reduce the amount of geometry sent to the hardware by using vendor specific stencil functions.


if(renderPath & NV_SHADOW_PASS || renderPath & ATI_SHADOW_PASS){
glDisable(GL_CULL_FACE);

if(renderPath & ATI_SHADOW_PASS){
glStencilFuncSeparateATI(GL_ALWAYS, GL_ALWAYS, 0, ~0);
if(needZFail){
glStencilOpSeparateATI(GL_FRONT, GL_KEEP, GL_DECR_WRAP_EXT, GL_KEEP);
glStencilOpSeparateATI(GL_BACK, GL_KEEP, GL_INCR_WRAP_EXT, GL_KEEP);
}
else
{
glStencilOpSeparateATI(GL_FRONT, GL_KEEP, GL_KEEP, GL_INCR_WRAP_EXT);
glStencilOpSeparateATI(GL_BACK, GL_KEEP, GL_KEEP, GL_DECR_WRAP_EXT);
}
}

if(renderPath & NV_SHADOW_PASS){
if(needZFail){
glActiveStencilFaceEXT(GL_BACK);
glStencilFunc(GL_ALWAYS, 0, ~0);
glStencilOp(GL_KEEP, GL_INCR_WRAP_EXT, GL_KEEP);
glActiveStencilFaceEXT(GL_FRONT);
glStencilFunc(GL_ALWAYS, 0, ~0);
glStencilOp(GL_KEEP, GL_DECR_WRAP_EXT, GL_KEEP);
}
else
{
glActiveStencilFaceEXT(GL_FRONT);
glStencilFunc(GL_ALWAYS, 0, ~0);
glStencilOp(GL_KEEP, GL_KEEP, GL_INCR_WRAP_EXT);
glActiveStencilFaceEXT(GL_BACK);
glStencilFunc(GL_ALWAYS, 0, ~0);
glStencilOp(GL_KEEP, GL_KEEP, GL_DECR_WRAP_EXT);
}
glEnable(GL_STENCIL_TEST_TWO_SIDE_EXT);
}
}
else
{
if(needZFail){
glStencilOp(GL_KEEP, GL_INCR, GL_KEEP);
glCullFace(GL_FRONT);
shapes[s]->doShadowPass(lightPosObjSpace, needZFail);
glStencilOp(GL_KEEP, GL_DECR, GL_KEEP);
glCullFace(GL_BACK);
}
else
{
glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
glCullFace(GL_BACK);
shapes[s]->doShadowPass(lightPosObjSpace, needZFail);
glStencilOp(GL_KEEP, GL_KEEP, GL_DECR);
glCullFace(GL_FRONT);
}
}
shapes[s]->doShadowPass(lightPosObjSpace, needZFail);
}
}





No need for any other passes :)



[Edited by - JavaCoolDude on August 22, 2004 4:37:57 AM]

Share this post


Link to post
Share on other sites
Daivuk, you lighting model is flawed. Because you accumulate all the light intensities together and only modulate by your texture once at the end you'll loose a whole load of precision and won't get proper overbright behaviour. You need to do a texture modulation after every light pass.

Share this post


Link to post
Share on other sites
JavaCoolDude : Nice screen shot :):), with specular bump hen? So you mean draw the scene first with an ambient .1f,.1f,.1f?
Ok, but if I want the dark to be totaly black? :P

Quote:

OrangyTang Daivuk, you lighting model is flawed. Because you accumulate all the light intensities together and only modulate by your texture once at the end you'll loose a whole load of precision and won't get proper overbright behaviour. You need to do a texture modulation after every light pass.


Hum, that's a good idea :). Its true that I lost a lot of precision. All become too bright. Thanks. Ya, I can use multitexturing of course :P.

But, I will not update my tutorial with thoose modif, probably another little tut à the end. Because I want to show the basic and the base of the concept first :). But I will probably add those at the end (to enhance your visual aspect). And your names of course : proposed by :

Share this post


Link to post
Share on other sites
Quote:
Original post by Tree Penguin
I don't see how your method has precision loss, can yuo explain it to me?

If the combined lights' intensities go over 1 then they'll be clamped to 1 in the framebuffer. That means that the final texture pass can only ever be at normal texture brightness. If you do a texture pass per light then the texture intensities from each light are added individually which gives a much greater range of light values (and proper overbright behaviour).

Share this post


Link to post
Share on other sites

This topic is 4864 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.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this