A conceptually simple(r) way to derive exponential shadow maps + sample code

A few months ago, while working on an improved version of exponential shadow maps, I stumbled on a new way to derive ESM equations which looks more simple and intuitive than previous attempts.

There is no need to invoke Markov’s inequality, higher order moments or convolutions. In fact all we have to do is to write the basic percentage closer filtering formula for n equally weighted occluders o_i and a receiverr


The role of the step function H(x) is to perform a depth test on all occluders, depth test results are then averaged together to obtain a filtered occlusion term. The are many ways to write H(x) and a limit of exponential functions guarantees a fast convergence:

\displaystyle H(o_i-r) = \lim_{k \to +\infty} \frac{e^{ko_i}}{e^{ko_i}+e^{kr}}

We can rewrite the original PCF equation as:

\begin{array}{ccc} \displaystyle\frac{1}{n}\sum_{i=1}^{n}H(o_i-r)&=&\displaystyle\frac{1}{n}\sum_{i=1}^{n}\lim_{k \to +\infty} \frac{e^{ko_i}}{e^{ko_i}+e^{kr}} \\ &=&\displaystyle\lim_{k \to +\infty}\frac{1}{ne^{kr}}\sum_{i=1}^{n}\frac{e^{ko_i}}{e^{k(o_i - r)}+1} \end{array}

If we make the hypothesis that our shadow receiver is planar within the filtering window we are also implicitly assuming that the receiver is the most distant occluder (otherwise it might occlude itself, which can’t happen given our initial hypothesis), thus we have r > o_i.
Armed with this new assumption we observe that the term e^{k(o_i - r)} quickly converges to zero for all occluders:

\begin{array}{ccc} \displaystyle\lim_{k \to +\infty}\frac{1}{ne^{kr}}\sum_{i=1}^{n}\frac{e^{ko_i}}{e^{k(o_i - r)}+1} &\approx&\displaystyle\lim_{k \to +\infty}\frac{1}{ne^{kr}}\sum_{i=1}^{n}e^{ko_i} \\ &\equiv&\displaystyle\lim_{k \to +\infty}\frac{E[e^{ko}]}{e^{kr}} \\ \end{array}

As we already know k controls the sharpness of our step function approximation and can be used to fake soft shadows. Ultimately we can drop the limit and we obtain the ESM occlusion term formula:

\displaystyle \frac{E[e^{ko}]}{e^{kr}}

Exponential shadow maps can be seen as a very good approximation of a PCF filter when all the occluders are located in front of our receiver (no receiver self shadowing within the filtering window). There’s not much else to add, if not that this new derivation clearly shows the limits of this technique and that any future improvements will necessarily be based on a relaxed version of the planar receiver hypothesis.

For unknown reasons some old and buggy ESM test code was distributed with ShaderX6. You can grab here the FxComposer 2.0 sample code that was meant to be originally released with the book.

Another brief update: GDC08 and ShaderX6

How do you feel right before giving the first lecture of your life? The answer is: not well!

I felt so tense that I forgot half of what I wanted to say, and even though I was probably speaking a bit too fast I believe my lecture at GDC went quite well. The room was packed with people, despite the fact that was the last talk of the day. At the end of the presentation I was asked a fair number of pertinent questions, and I was kind of surprised to realize that some didn’t believe that such extremely simple approaches could possibly work!

For all those that couldn’t come be there Wolfgang Engel (organizer of the Core Techniques & Algorithms in Shader Programming day at GDC) has collected all the presentations in one handy page. You can also download my presentation about some new and exotic shadow mapping filtering schemes directly from this link. Comments were added to the most obscure slides and as usual feel free to ask questions, comments, point out errors, etc.. on this blog.

This talk was also represented the first occasion to publicly introduce Exponential Shadow Maps. The main idea has been going around for a while now (and it seems some highly anticipated game will soon ship with it..) but it wasn’t possible to fully explain the algorithm and why it works (or doesn’t work, in some case:) ) due the limited amount of time available.

On the other hand ShaderX6 is now widely available and you will be able to find in it a long and detailed article about ESM (and some sample code), among many other interesting contributions.