Jump to content
  • Advertisement
Sign in to follow this  
bencelot

OpenGL Projecting 2D Shadows onto 3D.

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

Hey all, I'm using OpenGL and I want to project my generated 2D shadows onto my 3D map. I'm generating the shadows in a similar way as is described here: http://www.gamedev.net/reference/articles/article2032.asp Basically this involves rendering polygons of varying intensity into the alpha buffer, and once all the shadows are drawn, drawing 1 big black quad over the entire screen using: glBlendFunc(GL_ZERO,GL_ONE_MINUS_DST_ALPHA); Currently, I've got these 2D shadows working nicely.. they're soft and dynamic. The problem is that they lie flat along the ground. Which means they cast shadows only on a flat plane (height 0). What I want is for these shadows to move up and over the top of any buildings that lie in the way. Is it possible to project these 'shadow polygons' onto the map from up top. So instead of drawing a quad at height 0, I orthographically project this quad downwards onto the map. So that if there are any buildings or objects in the way, this quad will be drawn ontop of them and down the sides.. not just underneath them (where it isn't drawn due to the depth testing. Note also that I'm not looking for the effect achieved by just disabling depth testing.. I want the shadow to actually go up and over the building in 3D). Anyway, sorry for the long post. I've looked around at projective texturing, but I really don't know where to start, so I've tried to include as much info as I can. P.S. I'd rather not have to use shaders, as I'm targetting the windows platform and my understanding is that if I use extensions it'll not work on all computers, or something. Please clarify if I've misunderstood. Thanks! Ben.

Share this post


Link to post
Share on other sites
Advertisement
What you probably want to do is render the shadows into a separate texture so you end up with a lightmap texture with dark black areas of shadow and white areas which are fully lit. Then when you draw your actual world you can project the lightmap texture over the objects as you draw them to get the shadowing applied correctly to them.

HTH.

Share this post


Link to post
Share on other sites
So I basically render my shadows to a seperate texture (rather than the alpha buffer), then I do something like:

glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, newlyCreatedShadowMap);

glEnable(GL_TEXTURE_GEN_R);
glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
//some other steps to get this texture to project directly down
//I'm not even sure if I should be using GL_R, either..

map.Draw();

glDisable(GL_TEXTURE_GEN_R);


2 questions:

1) will that screw with the textures I'm currently drawing on my map? Like grass & road and whatnot.

2) how easy is it to render to a separate texture rather than the alpha buffer? Is it faster/slower? Does it require extensions, or can I do this with version 1.0? Just for the record.. what's the deal with using extensions on windows, anyway? What are the compatibility issues involved?

Thx

Share this post


Link to post
Share on other sites
1. You'll have to use multitexturing, so that you're using both the material texture (grass, road, etc.) and the shadow texture. For multitexturing the default is to multiply the two together (which is what you want).

2. The easiest way is to draw your shadow stuff to screen, then use glCopyTexSubImage to copy it into a texture. This is pretty fast (just make sure to reuse the texture rather than making a new one each time). Then you clear your screen and draw your actual world. This works in basic GL1.1.

The forum faq has details about using extensions on windows. And I can never remember how you set up projective texturing but I think NeHe has a tutorial demonstrating it.

Share this post


Link to post
Share on other sites
hmmm, my shadows are dynamic though. They have to be updated each frame, which would probably be too slow, right?

Share this post


Link to post
Share on other sites
Nope, you can re-render and update that texture every frame and it'll be fine. I've had dynamic lightmap stuff like this working just fine at 60fps even on those terrible intergrated intel graphics chips.

Share this post


Link to post
Share on other sites
hmm, ok might be the way to go.

But just out of curiousity.. is there ANY way at all (even with shaders), to get this same projection effect via direct rendering?

I mean.. instead of rendering whatever you want to project to the frame buffer, then copying it to a texture, and then projecting it onto the geometry.. instead all you have to do is simply draw whatever you want projected (in my case a black shadow quad), and have it automatically project onto the existing geometry. Like you set a direction, and then render away.

Also.. another problem with projecting via a texture is that I need to continue using the generated shadow map after rendering the shadows. After the map is drawn, any in-game objects become transparent when in the shadow region using:
glBlendFunc(GL_ONE_MINUS_DST_ALPHA,GL_DST_ALPHA);

Thus.. the shadow values in the alpha buffer need to be where they appear in 3D (like on top of a building).. not where they are calculated in 2D at height 0. So to do this.. I'd have to:

1) Render 2D shadow areas to framebuffer (with shadow intensity ranging from white to black)
2) Copy to texture
3) Draw map with projected texture only (rendering only to alpha). This will bring the existing 2D shadow areas up ontop of buildings, resulting in a 3D shadow map stored in the alpha buffer)
4) Draw map with grass and road textures (into rgb, not alpha)
5) Draw in-game objects, fading opacity based on alphabuffer intensity
6) Draw a big black quad over the screen using:
glBlendFunc(GL_ZERO,GL_ONE_MINUS_DST_ALPHA); ..to fill in the shadows.


however, it MIGHT be possible to combine steps 4 and 6 into step 3, so I'm rendering with multitexturing, like you suggested. But I can only do this on the condition that I can render the projected texture and ONLY the projected texture (the shadows) into the alpha buffer, so that I might later use it to make my ingame objects transparent when they're in the shadow (out of line of sight).

Does this sound accurate/possible?
Thx

[Edited by - bencelot on July 25, 2008 6:20:04 PM]

Share this post


Link to post
Share on other sites
ok, I'm trying out this glCopyTexSubImage thing now. But first I need to make the texture.. I just realised that if someone resizes the window.. I won't be able to copy the entire framebuffer into the texture, will I?


So would it be best for me to delete/create a new texture everytime the window size is changed?

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!