I'm working on a shadow-mapping implementation for an OpenGLES 2.0 environment (Stage3D in Flash to be exact). This is how my current implementation works:

Render the scene to backbuffer.

Render depth map from the light's point of view.

Render shadows on a texture from the camera's point of view.

(Do blur and other effects to improve the shadow texture, not implemented yet)

Render the shadow texture to the backbuffer with multiply.

Some pictures to help explaining. Note that the bunny is floating in the air on purpose.

Shadows rendered on a texture from the camera's view.

The final scene with shadow texture rendered on top with multiply.

The problem is the unshadowed pixels at the bottom of the bunny. Because the shadow texture is rendered with linear filter, the edge of the shadow loses its sharpness. This is mostly a good thing but not everywhere. I would like to do more filtering effects on the shadows but they would cause even bigger issues.

I haven't encountered this kind of problem in any tutorials or forums so either there is an obvious solution for this or there is something wrong with my approach. The question is, can I solve this somehow using my current approach? Or is there a bigger gap in my method?

Great. Sadly I haven't much to say to your question. Maybe you can apply a larger blur so that you retain soft edges and the artifacts won't stand out anymore.
–
danijarFeb 24 '13 at 11:48

I've thought about that and I'm concerned about another problem that would arise: The shadows would start covering areas that shouldn't be in shadow. I have a strong feeling that the whole approach is wrong...
–
JohannesAFeb 24 '13 at 11:54

1

You could blur based on depth differences to avoid that. But as you said there might be a overall better approach I don't know about.
–
danijarFeb 24 '13 at 12:44

1 Answer
1

In general, the way that shadow maps are supposed to work is not by combining a screen-space shadow texture with a rendered texture. In that case you will always get awkward artifacts at boundaries between fully-lit areas and fully-shadow areas that have similar z-values. These are the areas where you're sampling at a boundary in the shadow map.

The preferred method is to use a shadow-map as an additional texture to the scene that you're rendering. In this way, before you render a final pixel, you map that pixel's position to the coordinate space from the light's point of view, and test it against the z-value in the shadow map. From here you can multi-sample the shadow map and get a better idea whether or not the pixel is in shadow. The general algorithm is:

Render depth map from the light's point of view.

Render the scene from the camera's point of view and test whether or not pixels are in shadow

There is a great tutorial available about this (in regular OpenGL but the techniques still apply to ES 2.0) here: