Translucent Shadows Part I - Starcraft II

Shadows is an important visual cue for rendering and has been incorporated into recent games via shadow mapping technique. Most shadow mapping technique only concerns about opaque object shadows and there is not a lot of about translucent object shadows.

Translucent Shadows in Starcraft II Review
In Starcraft II - Effects & Techniques, Dominic Fillion mentions how they render translucent shadows in Starcraft II. Here's how the rendering works:

Notes:
* Requires second shadow map and color buffer. Let's name them as translucent shadow map and translucent shadow buffer.

Shadow Maps Rendering
* Opaque Shadow Map: render opaque objects to opaque shadow map
* Translucent Shadow Map: render translucent objects to translucent shadow map (z-write on, z-test on with less equal, no alpha test, records depth of closest transparency)
* Translucent Shadow Buffer: Clear to white, sort translucent objects front-to-back, use Opaque Shadow Map as z-buffer, no z-write off, z-test on with less equal, records color information for transparencies in front of opaque objects

Scene Rendering
* Test both opaque shadow map and translucent shadow map
* if (translucent shadow map test fail) module by color of transparent shadow color bufer
* Modulate by result of opaque shadow map test (binary test)

Things to note:

  • The technique completely separates opaque shadows and translucent shadows (that's why they have 2 shadow maps)
  • This technique handle self-shadowing correctly for both opaque objects and translucent objects
  • Translucent shadow buffer might not be necessary if we don't need colored shadows
  • If we are just doing hard shadows or 1 sample per shadow map, the opaque shadows and translucent shadows can be combined simply by modulation, i.e
  • vis = opaqueShadowVis * translucentShadowVis
  • In general case, if we want soft-shadows, we basically need to sum the visibility and divide by number of samples, i.e.
  • vis = 0
    for (i=0; i != num_samples; i++)
        vis += opaqueShadowVis[i] * translucentShadowVis[i];
    vis /= num_samples;
    
  • Remember, here we are talking about binary tests! so opaqueShadowVis and translucentShadowVis are point sampled.

Comments

Popular posts from this blog

GDC 2015 Links

D3D11 Compute Shader - Part 1

Mapping Square Texture to Trapezoid / Quadrilateral