1. Massive Point Light Soft Shadows
Wolfgang Engel
Confetti Special Effects Inc.
September 14th, 2010
2. Confetti Special Effects
• Think-Tank for advanced real-time graphics
research
• Targeting video game and movie industry
• Website: (click on “Like” on this page )
http://www.facebook.com/pages/Confetti-Special-Effects-Inc/159613387880?v=wall
3. Agenda
• Motivation
• Basics of Soft Shadows
• Point Light Soft Shadow Rendering
Architecture
• Min-Z Map
• Collect Shadow Data in Screen-Space
• Screen-Space Anisotropic Filtering
4. Motivation
• We can render thousands of point lights
• We need at least dozens of point light soft
shadows and many more regular point light
shadows
• Fundamental for future development of more
complex light and shadow effects like Global
Illumination with a Global Occlusion / Shadow
term
7. • PCSS searches red region for blockers
– Blocker is defined by being closer to light than receiving
point
– Averages depth values of blockers
– Averaged depth value used for penumbra size estimation
Basics of Soft Shadows
8. • Blocker search
// is it a blocker?
if (shadMapDepth < receiver)
{
blockerSum += shadMapDepth;
blockerCount++;
foundBlocker = 1;
}
…
// return average depth of the blockers
result = blockerSum / blockerCount;
Basics of Soft Shadows
9. • How to calculate the scale factor for the penumbra
• dBlocker – the result of the blocker search
• dReceiver – the depth of the pixel that is currently rendered
• wlight – the light size
Basics of Soft Shadows
10. Rendering Architecture
For Point Light Screen-Space soft shadows we
are going to change mainly two things:
1. Replace blocker search with a minimum Z-
map or dilated shadow map [Gumbau]
-> Blocker search is expensive
2. Anisotropic Screen-Space Filter Kernel
instead of Light-Space filter kernel
-> Screen-Space is less expensive
11. The algorithm in steps:
1. Calculate the cube shadow map
2. Generate min Z map [Gumbau]
3. Blend the “unfiltered” exponential shadow map data of all
cube maps into a screen-space shadow map
4. Based on each min Z map, calculate
a. The x and y offset values for the filter kernel based on
• Adjustment based on distance from camera
• Penumbra size [Fernando]
• Anisotropic kernel adjustment [Geusebroek]
b. Early out value (optimization) [Gumbau]
-> store the end result in a screen-space texture
5. Apply a screen-space anisotropic Gaussian filter kernel
based on 4.
Rendering Architecture
12. Min-Z Map
• Blocker search
• is used to determine the distance of the shadow
blockers -> dBlocker
• this is used to determine the penumbra width
• Minimum Z map represents the minimum Z values
== closest to the lights of the whole scene
~ kind of like blocker data
13. Min-Z Map
• Generated from the shadow map
• Into a lower res render target == coarse shadow map
== one pixel represents an area of the orig. shadow
map
-> runs only CoarseMapsizeX * CoarseMapsizeY times
-> fast
• 2 pass filter kernel that returns the minimum Z
values of its area in light space
14. Min-Z Map
• Issue: maximum size of penumbra restricted by size
of filter kernel
-> no way to figure out max size of the penumbra
-> sensible user defined constant value that scales up
filter kernel
• too high -> artefacts
• too low -> loose of softeness
• In other words: filter kernel is determined by a
• value representing the light size
• + value that is the magic user defined constant
15. Min-Z Map
• Advantage of Min-Z map approach
• much faster
• … therefore allows soft cube shadow maps
• Disadvantage: min-Z value not only from
blockers but for the whole lit scene
-> min-Z aliasing
16. Collect Shadow Data in Screen-Space
Cube map == exponential shadow map [Salvi]
float depth = tex2D(ShadowSampler, pos.xy).x;
shadow = saturate(2.0 - exp((pos.z - depth) * k));
• Approximate step function (z-d> 0) by
exp(k*(z-d)) = exp(k*z) * exp(-k*d)
Good overview on the latest development in [Bavoil]
17. • All the shadow data is just blended via
BLEND_ADD into a screen-space texture
• This texture can be called shadow collector or
shadow mask
Collect Shadow Data in Screen-Space
18. Screen-Space Anisotropic Filter Kernel
• Why a screen-space filter kernel?
• In light space we filter per shadow map
• In screen-space we filter only once for all
shadow maps
-> many light sources
-> advantage
19. Screen-Space Anisotropic Filter Kernel
• What we need to do:
• Determine the filter kernel offset values
that scale the filter kernel
• Write “offset” values for all shadow maps
into a screen-space render target
• … the Gauss filter will read those values
later from there
20. Screen-Space Anisotropic Filter Kernel
• What are the values required for the Gauss filter?
1. The x and y offset values for the filter
kernel are based on
a. Adjustment based on distance from
camera
b. Penumbra size & Light size[Fernando]
c. Anisotropic kernel adjustment
[Geusebroek]
2. Early out value (optimization) [Gumbau]
• … store those values in a 16:16 fp render target
or calculate them on the fly while filtering
21. Distance to the Camera
• Screen-space filter kernel is getting bigger with
increasing distance because of the projection
-> decrease kernel size with with increasing
distance
• Simple way to do this is 1.0 / (distance2 * bias)
~ light attenuation
• This requires a linear depth value in camera space [Gillham]:
float depthLin= (-NearClip * Q) / (Depth - Q);
Q = FarClip / (FarClip – NearClip)
Depth = value from depth buffer
• Source code:
// scale based on distance to the viewer
sampleStep.xy = TexelSize.zw * sqrt(1.0f / ((depthLin.xx * depthLin.xx) * bias));
22. Penumbra Size
• To calculate the Penumbra, [Fernando]
suggested the following equation
• We use as is, just modified by the “distance to
camera” scaling value
23. Anisotropic Filter Kernel Adjustment
• Anisotropic filter kernel: round filter kernel
projected into ellipse following the orientation
of the geometry [Geusebroek]
-> need to determine the shape and
orientation of this ellipse
float Aniso = saturate(sqrt(dot( viewVec, normal )));
24. Screen-Space Anisotropic Filter Kernel
• Screen-space challenges
• Filter kernel can smear values into the penumbra around
corners of geometry
• Compare Z value of pixel with Z value of shadow map tap
bool isValidSample = bool( abs(sampleDepth - d) < errDepth );
if (isValidSample && isShadow)
{
// the sample is considered valid
sumWeightsOK += weights[i+1]; // accumulate valid weights
Shadow += sampleL0.x * weights[i+1]; // accumulate weighted shadow value
}
25. Screen-Space Anisotropic Filter Kernel
• Screen-space challenges
• “Light in a box” or occlusion of shadow data in
general -> should not affect Gauss filter -> need to
deal with occlusion or ignore it (game specific)
• Overlapping shadows in screen-space
-> starts with the philosophical question: what
kind of entity are shadows?
26. Tips & Tricks
• Seriously! Who needs 64 Point light shadows
perceptually correct on screen
• switch off when the lights are fast
• Far away
• .. . or in all other cases you can think off
• How to render shadow data into a cube map
-> fill up a texture array; then type cast to
cube maps
• Try Dual-Paraboloid Shadow Maps … might be faster
with DX10 / 11 … I didn’t try so far
27. Massive Soft Point Light Shadows
16 Point Light Soft Shadows filtered in screen-space
28. Massive Soft Point Light Shadows
32 Point Light Soft Shadows filtered in screen-space
29. Massive Soft Point Light Shadows
64 Point Light Soft Shadows filtered in screen-space
31. Confetti Special Effects
• Is looking for
– Investors
– Contract work
– Offers support to young researchers at
Universities that are interested in game related
real-time research
33. References
• [Bavoil] Louis Bavoil, “Advanced Soft Shadow Mapping Techniques”
http://developer.download.nvidia.com/presentations/2008/GDC/GDC08_SoftShadowMappin
g.pdf
• [Fernando] Randy Fernando, “Percentage-Closer Soft Shadows”, SIGGRAPH 2005
• [Forsyth] Tom Forsyth, “Making Shadow Buffers Robust Using Multiple Dynamic Frustums”,
ShaderX4, pp. 331 – 345
• [Geusebroek] Jan-Mark Geusebroek, Arnold W. M. Smeulders, J. van de Weijer, “Fast
anisotropic Gauss filtering”, IEEE Transactions on Image Processing, Volume 12 (8), page 938-
943, 2003
• [Gilham] David Gilham, "Real-Time Depth-of-Field Implemented with a Post-Processing only
Technique", ShaderX5: Advanced Rendering, Charles River Media / Thomson, pp 163 -
175, ISBN 1-58450-499-4
• [Gumbau] Jesus Gumbau, Miguel Chover, and Mateu Sbert, “Screen-Space Soft Shadows”,
GPU Pro, pp. 477 - 490
• [Waliszewski] Arkadiusz Waliszewski, “Floating-point Cube Maps”, ShaderX2 – Shader
Programming Tips and Tricks with DirectX9, Wordware Inc., pp. 319 – 323.
http://www.realtimerendering.com/blog/shaderx2-books-available-for-free-download/