I finished implementing some shadows! Basically I ripped the code from the DirectX SDK, the CascadedShadowMaps11 sample. There’s a few things I had to do to adapt it for use on a planetary surface though (as opposed to the tiny scene box in the sample).
The most major change was that I had to now create a “scene” space dynamically as the camera moves around, to use as a basis for calculating the shadow map projections. Ideally the camera should be close to the origin in that space, so that calculations can be done in 32-bit precision on the GPU. So for the scene origin, I decided to snap the camera coords to 100 meter increments. That way, the camera would never be more than 100m away from the scene’s origin.
Secondly, all the shadow casters (only rocks at the moment) need to be translated into the new scene space before rendering into the shadow maps. I have to generate a scene bounding box dynamically to best fit the shadow maps to the casters. The visible rocks are used for this, and very distant rocks are discarded when performing the max/min tests, resulting in a reasonable depth range for each shadow texel, but limiting the shadow range to 2km. The rocks are also culled against the shadow cascade frustums before rendering them into the shadow maps, to avoid wasting the GPU’s time.
I also decided to use a texture array for the shadow maps. Unfortunately though the SampleCmpLevelZero function in HLSL 4 apparently won’t work on a texture array, which is quite annoying. This means I have to use the SampleLevel function instead when sampling the shadow maps, and then doing the depth comparison manually. This results in aliased shadow edges, although I have noticed many commercial games have displayed the same artifact. If it annoys me enough, I guess I’ll change the code back to how the original sample worked in that regard – by having one big shadow map texture and dividing it up into pieces for the different cascades.
But for now I’m quite happy with the results and I’ve been quite impressed with how much “depth” the shadows give to the final image. 🙂
A really hot planet. Note shadows interacting with the bloom!
The rocks are also all generated on the fly, and each one is different. I think they’re still a bit boring though, I’ll definitely be doing more work on those at some point.
The terrain doesn’t cast shadows yet. I am a bit worried about how that’s going to go from a performance point of view. I’m thinking of also implementing a “whole planet” shadow map to handle things like rings casting shadows, and eclipses.
Planning on releasing a new video of the project soon…