10
\$\begingroup\$

How could I implement 2d shadows that are cast by objects in a different layer?

NOT like the dynamic lighting in the well known tutorial from Catalin Zima :

enter image description here

But like the shadows of the pipes in this video:

enter image description here

And like the shadow of the platform and the character in this video:

enter image description here

I would like to use the same kind of lighting in a scene with many layers and a lot of lights with different colors.

I could imagine doing this by drawing a black copy of the layer over the layers behind that layer, and adjusting it according to holes in the layers on which the shadow is cast. But I hope there is a less expensive, pixel-shader based approach for this.

\$\endgroup\$
1
\$\begingroup\$

This can be done with masking. There are multiple ways to do it.

One way would be to have a way to render a shadow version of foreground elements. Draw the background. Then draw the foreground elements, offset slightly depending on how you want lighting to move, in such a way that you only output black colors. Then draw the foreground normally.

Another way would be to render the foreground into a buffer, a little bit more than you'd actually see. Then do some "to black" pass and maybe a blur pass. Now render the output of this set of passes and then the visible section of the foreground buffer.

To support multiple lights at different angles, you can just do the previous step multiple times, or accumulate them all in a single buffer. The math will vary based on what you're trying to achieve, but a first guess at what's going on in that first video is that they just take the position of the light against the position of the camera (center of the visible area) and then use that vector (scaled) to determine how to offset the shadows. Something like:

draw background
for each light intersecting viewing bounds:
  offset = light.position - camera.position
  offset *= SCALE FACTOR (0.25 maybe)
  draw shadow foreground at offset
draw foreground

Lights that are "closer" to the scene will have a smaller scale factor. If you want multiple depths, there's some math to work out there, simple geometric stuff.

\$\endgroup\$
  • \$\begingroup\$ Yeah this is exactly what I came up with myself. Didn't know the correct term for it was masking though. But I hoped there maybe would be an algorithm more similar to how shadow volumes work in 3D space.. \$\endgroup\$ – Berry Jul 8 '13 at 19:34
  • \$\begingroup\$ When you are casting shadows over surfaces with holes in them, you have to cast the resident shadow over the layer behind that one. Also, working with transparency will become a bit tricky. I already thought of all the solutions for these problems! But I thought it would become too expensive to apply in real time, especially when dealing with lots of layers (20) and a lot of lights (50). That's why I hoped for a different approach. \$\endgroup\$ – Berry Jul 8 '13 at 19:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.