-=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- (c) WidthPadding Industries 1987 0|434|0 -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=-
SoCoder -> Blogs Home -> Blogs

Created : 28 April 2013
System : PSP

Top-Down Shadow Hack

(Note: copy/pasted this from Google+ because nobody reads Google+ and I'd originally shared it privately.)

So I had this brilliant idea for doing 2D shadows in a topdown thing. While I was playing Teleglitch earlier, or the beta demo thing for OS X anyway, I kept wondering how you could do simple hard shadows really fast. One way, which is sort of the obvious way, is to simply take all your shadow-casting things (e.g., walls, doors, etc.) and project a shadow polygon out and draw that over everything beyond the caster (or use stenciling — this would let you kill a lot of fragments early, but anyway). So far as I know, Teleglitch goes this sort of route.

The other, hackier option I decided to try out is actually fairly simple: for each shadow caster, provide an unlit, black box that extends well above the 'camera'. The camera should have perspective projection and always be looking down, but otherwise, the important thing is that the box goes a ways behind the camera's z-min. Now you basically just let the projection take care of shadow-casting.

View on YouTube

In practice, if you want to actually draw visiblity, this doesn't work unless you keep the camera fixed on the player. If you move it away from the player, in this case, the shadow boxes will obscure things that can be seen and show things that can't.

So, it's not a great solution if you want the shadows as a core gameplay thing (and in Teleglitch's case, they're very important for basically keeping the game tense and making sure you don't know what's around a corner or behind a door [though you know it's probably a mutant]). Was a fun little thing to try, anyway. Probably good for prototyping stuff, probably not good if the shadows/visibility are a gameplay mechanic.



Sunday, 28 April 2013, 13:24
That looks awesome!
Would be nice in a dungeon romp / mini RPG type thing.
Sunday, 28 April 2013, 15:49
Or, you know, you could just do Carmack's Reverse, aka Shadow Volume...
Monday, 29 April 2013, 02:20
1) That doesn't apply, 2) it's patent-encumbered.
Monday, 29 April 2013, 05:51
I have often wondered how to achieve this in a 2D environment.

Would it be easier to let the 3D engine work it out or come up with a tailored design?
Monday, 29 April 2013, 12:48
Unless you've got an engine that somehow knows to cast shadows for 2D objects and knows how to give those objects depth, you will have to design something yourself. 3D shadowing techniques generally do not apply in 2D, except with respect to using the stencil buffer to define where a shadowed area is.

You could fairly easily do proper 2D lighting in multiple passes by rendering the shadow polygons to the stencil buffer and then either using a) a cookie or b) per-pixel lighting to draw the lit area and light radius. This allows for both additive and multiplicative lighting as well and light order should be mostly unimportant in those cases (|edit| barring the usual order of operations stuff with addition/multiplication |edit|). The only downside to this is that if the light sources change position, you'll have to recalculate the shadow polygons, which could possibly be expensive if you've got a lot of shadow-casters on-screen.

In GL2, you could also do this by specifying clipping planes and drawing a full-screen quad (optionally also scissoring to prevent too much overdraw), but this is deprecated in the GL core API now. So, just use polygons and stencil buffers.
Monday, 29 April 2013, 19:19
You could take the Sims approach - lightmaps!
Basically, instead of mapping shadows, this technique maps lights and then uses those maps to calculate (in real time!) which parts of the scene are shadowed. This is an early form of real-time shadowing, though shadows are not dynamic.
I think this technique requires your sprites to be z-buffered, but I won't say that as a fact. Cower probably knows.
Monday, 29 April 2013, 19:21
For an example, look at (about 0:55):

View on YouTube
Tuesday, 30 April 2013, 01:52
How the hell is that anything remotely like Cower's effect?!
Cower isn't creating "a bit of a shadow", he's creating a blackout effect that hides surrounding elements.
Sims shadow is to give a lighting effect.
Noel's shadow could potentially unlock gameplay situations, hide elements and bring all new functionality to the engine.

They're completely different.
You're comparing an Apple to a Trombone!!
Tuesday, 30 April 2013, 02:31
Side-note: when I was seven or eight, I had a pet chicken named Trombone. She was a black hen. Don't think I ever knew what kind she was, specifically.
Tuesday, 30 April 2013, 03:48
"Sims shadow is to give a lighting effect."

No it isn't!
Notice how the shadows are calculated immediately as the walls are created...
Tuesday, 30 April 2013, 04:05
Shadows in The Sims aren't calculated nor really lightmaps - they're just little overlay gradients on grass tiles where a wall meets their edges. Note that this doesn't apply to wall intersections, only walls that run along edges. Note how the shading always goes in the same direction and only applies to grass.

Really, The Sims has incredibly unsophisticated graphics and is a terrible example of how to handle lighting. It doesn't use lightmaps and it doesn't use realtime shadows in the sense that this post is discussing. It has no relevance to discussions of lighting in games.

Also, when did I stop having the highest scorebar thing? That's demotivating.
Tuesday, 30 April 2013, 04:08
Sorry, My fault, I tend to make a lot of games!
Tuesday, 30 April 2013, 04:41
only applies to grass.


It doesn't use lightmaps


Jay, you couldn't make anything like The Sims even in Blitz 3D if you tried...
Tuesday, 30 April 2013, 06:52
Of course I could. It would just require any form of artistic talent, as well as a teensy bit more than my regular weekly schedule.

But it's easily doable.