Figure 1: A screenshot of the Dynamic Shadows app running within a web browser.

Launch app in new tab...

This is my first real experiment with shadow mapping in WebGL. I’ve always used shadow volumes in previous OpenGL work, but calculating and projecting visible edges in real-time in JavaScript seems unnecessarily onerous. Thus, I wanted to see how much of the process could be done on the GPU and whether this is a reasonably viable alternative for the kind of shadows I need.

At first I had some pretty horrible aliasing effects on surfaces with high incidence angles, but a bit of tweaking in the shader and I’ve been quite surprised at how good the results are, even without any filtering or blurring effects (which I’ll try later).

If you want to see what I mean about aliasing effects, go to the DISPLAY SETTINGS panel and reduce the Surface Opacity to near zero. Then set the date/time such that the Sun is quite close to the horizon. You should then be able to see an amount of jaggedness at the leading edge of each shadow block. Normally this is completely hidden by the opacity of the building facades, but it does illustrate the problem.

The key to getting a good result was not relying solely on the depth mask for all surfaces in the model. By testing each normal in the fragment shader, you don’t need to use the depth mask at all for any surfaces that face away from the light as you can assume that they are in shadow. This one tweak was enough to get rid of all sorts of visual glitches that occurred when the light source was near grazing incidence on both horizontal and vertical surfaces.


Change Log

0.0.1 2016-11-28

  • Initial release.

Click here to comment on this page.