130 likes | 358 Views
Real-time Soft Shadows in XNA. Aaron Schultz. How to render shadows?. Idea: Objects close to a light shadow those far away. Anything we can see from the light’s POV is lit. Everything hidden is dark. Distance from light = Depth Render a depth map!. What is shadow mapping? . Pass 1:
E N D
Real-time Soft Shadows in XNA Aaron Schultz
How to render shadows? • Idea: Objects close to a light shadow those far away. Anything we can see from the light’s POV is lit. Everything hidden is dark. Distance from light = Depth Render a depth map!
What is shadow mapping? • Pass 1: • From light’s POV, render scene into a texture. Each pixel stores depth information. • Pass 2: • From camera POV, render scene to screen. For each pixel, compute position in light space. Compare stored depth (from pass 1) to current depth. • if( distanceToLight > storedDistance) //Hidden by occluder • In Shadow = true
Camera Space Light Space
What’s so difficult? • Aliasing = Really bad jaggies • Shadow map texels Not 1:1 camera pixels • Poor Precision = Banding, speckles, noise • How do we store depth? 16-bit? 32-bit? Floating-point? Fixed-point? • Different depths mapped to same value • Rounding errors
Naïve Solutions • Blur the shadow map or use hardware filtering • Still doing a binary compare = hard edges • Constant depth bias • Helps prevent “shadow acne” caused by precision errors • Doesn’t work well with the stretched shadow map (different bias needed at different points) • Causes Peter Panning From Common Techniques to Improve Shadow Depth Maps, MSDN
Getting Smarter… • Percentage Closer Filtering • Blur the *results* of multiple depth comparisons • Really expensive for any decent quality • Different encoding • VSM • Encode (depth, depth2). Extract to use as variance, compute probability of shadow • ESM • Encode depth. Extract • Both permit blurring the shadow map and using hardware filtering • **If the hardware supports the correct surface formats**
Really Smart… • Cascaded Shadow Maps • Put precision where we need it: close to the camera • Split camera frustum into pieces • Render separate shadow map for each sub-frustum Cascaded Shadow Maps, MSDN
Implementation Notes • What I Want: • RG32 (2 channel, 16-bit per channel), HW filterable, for VSM • R32F (1 channel, 32-bit), HW filterable, for Basic and ESM • What I Get: • Hardware filtering on floating-point formats disabled in XNA 4.0 (because actual support is only on Nvidia 8-series cards and up) • RG32 format (for VSM) unsupported on my machine • Access to… • RGBA1010102 • Color (4 8-bit channels) • All floating-point formats • Requires encoding VSM and ESM into Color to permit HW filtering (which is then mathematically wrong)
Implementation Notes • Normalize all depth values to [0,1] in the shader. Makes everything easier. • Remember the DirectX9 ½ pixel offset • So many places to mess up • Lots of converting between coordinate systems • Viewport settings, texture wrapping • Check hardware capabilities! • Get it to work first. Then optimize. • ESM not widely documented on the web • Most people do PCF wrong. Interpolation required! • XNA lets you focus on the algorithms (most of the time)
Let’s see the goods • (Demo)