Jump to content
  • Advertisement
Sign in to follow this  
roos

2D torch effect

This topic is 4759 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'm working on a 2D RPG and want to have the ability to make the screen dark, but have torches which light up the radius around them. Also, since it's a 2D game which will target older machines, the solution can't use shaders... So, my first idea was to use a full-screen overlay which is just black and 50% alpha. As for torches, this would be a bit trickier, but basically what I could do is use several overlays.. The area surrounding each torch would use an overlay which is black, with zero alpha in the center and increasing alpha towards the edges (to simulate falloff from the light). And the rest of the screen would just use plain black translucent overlays. Of course the problem is that so much alpha blending would kill performance especially on lower end machines. The other idea I had was using color modulation- i.e. just setting the color in each of the vertices when rendering to (.5, .5, .5) or something like that. As far as I know, color modulation is practically free, it's so cheap. The problem is that I can't use it to create the lighting effect from the torches. My solution then, is to simply combine modulation and blending. On the areas which are outside of the light source's bounding rectangle, I'll use modulation. Inside that area, I'll use overlays. It seems like maybe I'm making it too complicated though. What do you guys think? If anyone might have any feedback or ideas I'd really appreciate it. Thanks very much, roos

Share this post


Link to post
Share on other sites
Advertisement
I'm assuming you're planning to use OpenGL / D3D to do the blending/modulation work for you in hardware. I'm also assuming "older hardware" may not support render-to-texture.

If you have a high enough density of vertices it probably will be good to compute lighting at each vertex and colour modulate. As for alpha blending I think that's supported all the way back to the 3DFX Voodoo in hardware (though obviously the fill rate on the Voodoo was pretty low).

If you're lighting is strictly 2D then this lends itself to rendering one of the lighting and the geometry to screen and the other to a texture, and then modulating them together onto the screen (you can even get coloured lighting this way). For OpenGL the alpha blend settings would be something like GL_ONE, GL_ONE for accumulating the lighting layer and GL_DST_COLOR, GL_ZERO for doing the combining. Of course this requires support for render to texture and rectangular textures (though not the full non-power-of-2 textures extension). If you don't have render to texture you'll have to get the pixels from the framebuffer which is not a good thing to need to do, and if you don't have non-power-of-2 textures you'll either have to put up with a lower resolution light map or somehow use multiple squares with different textures for different parts of the lightmap.

With slightly newer hardware (you need alpha stored in the destination buffer - not common before 32 bit colour rendering), for non coloured lighting and providing non of your objects are transparent a better solution exists. Accumulate the contribution of each light into the alpha bits of the destination, disable alpha writing, then draw your geometry using GL_DST_ALPHA for source and GL_ZERO for the destination. Alternatively if some of your level geometry is transparent draw the geometry first, clear the alpha component, accumulate the lighting contribution and then draw a large polygon using GL_ZERO for source factor and GL_DST_ALPHA for the destination factor. There are quite a lot of variations on this approach so I'm not going to list all the possibilities I can think of.

Share this post


Link to post
Share on other sites
You could render all the lighting with additive blending (clear the screen to a dark grey rather than black to get ambient light), then all the rest from front to back with glBlendFunc(GL_DST_COLOR, GL_ZERO). This would limit you to using alpha tested (hard edged) sprites but it'll run fast on any hardware.

Share this post


Link to post
Share on other sites
Wow, thanks you guys rock :) I am still going to ponder about this some more, but you gave me some ideas about how to use different blending modes.

roos

Share this post


Link to post
Share on other sites
Quote:
Original post by Fingers_
You could render all the lighting with additive blending (clear the screen to a dark grey rather than black to get ambient light), then all the rest from front to back with glBlendFunc(GL_DST_COLOR, GL_ZERO). This would limit you to using alpha tested (hard edged) sprites but it'll run fast on any hardware.


Wouldn't that need a stencil buffer to measure coverage or something?

Share this post


Link to post
Share on other sites
No, just Z-buffer and front-to-back render order. In something like a 2D tile-based game this is as easy as "draw characters first, then the background". If everything's at the same Z depth, the Z-buffer test will prevent any pixel from being written to more than once. (The lighting pass would be done without writing to Z-buffer of course)

Share this post


Link to post
Share on other sites
Maybe this would help? :-) At least part up to "Hard-edged Shadow Casting" should be quite easy to implement, and it doesn't require any advanced tricks, only some blending in the torch area needs to be done, what should be rather fast even on low-end PC.

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!