Shadow Volume History (1)

• Invented by Frank Crow [’77] – Software rendering scan-line approach Shadow Volumes • Brotman and Badler [’84] – Software-based depth-buffered approach – Used lots of point lights to simulate soft shadows • Pixel-Planes [Fuchs, et.al. ’85] hardware – First hardware approach – Point within a volume, rather than ray intersection • Bergeron [’96] generalizations – Explains how to handle open models – And non-planar polygons

Shadow Volume History (2) Shadow Volume History (3)

• Fournier & Fussell [’88] theory • Dietrich slides [March ’99] at GDC – Provides theory for shadow volume counting approach within a – Proposes zfail based stenciled shadow volumes frame buffer • Kilgard whitepaper [March ’99] at GDC • Akeley & Foran invent the – Invert approach for planar cut-outs – IRIS GL functionality, later made part of OpenGL 1.0 • Bilodeau slides [May ’99] at Creative seminar – Patent filed in ’92 – Proposes way around near plane clipping problems • Heidmann [IRIS Universe article, ’91] – Reverses depth test function to reverse stencil volume ray – IRIS GL stencil buffer-based approach intersection sense • Deifenbach’s thesis [’96] • Carmack [unpublished, early 2000] – Used stenciled volumes in multi-pass framework – First detailed discussion of the equivalence of zpass and zfail stenciled shadow volume methods

Shadow Volume History (4) Shadow Volume Basics

• Kilgard [2001] at GDC and CEDEC Japan Shadowing – Proposes zpass capping scheme object • Project back-facing (w.r.t. light) geometry to the near clip plane Light for capping source Shadow • Establishes near plane ledge for crack-free volume near plane capping (infinite extent) – Applies homogeneous coordinates (w=0) for rendering infinite shadow volume geometry – Requires much CPU effort for capping – Not totally robust because CPU and GPU computations will not match exactly, resulting in cracks A shadow volume is simply the half-space defined by a light source and a shadowing object.

1 Shadow Volume Basics (2) Shadow Quality: Shadow Maps

Surface outside shadow volume (illuminated)

Simple rule: samples within a shadow volume are in shadow.

Partially Surface inside shadowed shadow volume object (shadowed)

Shadow Quality: Stencil Shadow Volumes Shadow Volumes

• Draw polygons along boundary of region in shadow (occluders) • Along ray from eye to first visible surface: – Count up for in event – Count down for out events – If result zero when surface hit, is lit • Can be implemented with stencil buffer • Near/far plane clip causes problems

Shadow Volume Advantages Point Inside 2D Polygon

• Omni-directional approach – Not just spotlight frustums as with shadow maps • Automatic self-shadowing – Everything can shadow everything, including self – Without shadow acne artifacts as with shadow maps • Window-space shadow determination – Shadows accurate to a pixel – Or sub-pixel if multisampling is available • Required stencil buffer broadly supported today – OpenGL support since version 1.0 (1991) – support since DX6 (1998)

2 Point Inside 2D Polygon Point Inside 2D Polygon

Point Inside 2D Polygon Point Inside 2D Polygon

• Infinite “polygon” • Union of polygons • Line segment

Optimizing shadow volumes Shadow volumes [Crow77]

• Use silhouette edges only • Shadow volumes define closed volumes of space that are in shadow L

A infinitesimal light source

shadow caster = light cap dark cap extruded side quads

3 Shadow Volumes [Crow 77] Shadow Volumes [Crow 77]

Front face: +1 Back face: -1 Step 1: Render scene  Z-values Step 2: Render shadow volume faces

Shadow Volumes [Crow 77] Shadow Volumes [Crow 77]

±0

Front face: ±0 (Depth test) Front face: +1 Back face: ±0 (Depth test) Back face: ±0 (Depth test)  =±0  =+1

Shadow Volumes [Crow 77] Shadow Volumes [Crow 77]

±0 +1 +1 ±0 ±0

Front face: +1 Back face: -1  =±0 Step 3: Apply shadow mask to scene

4 Illuminated, Shadow Volumes w/ Stencils (Zpass) Behind Shadow Volumes (Zpass)

• Details of the basic algorithm: – Compute shadow volumes • View-independent! Light Shadowing object – Clear stencil buffer source – Render the scene without (diffuse) specular lighting (ambient only) • Sets the Depth Buffer and color buffer – “Render” front faces of shadow volumes zero +1 • Turn off color, depth updates (but leave depth test on) • Visible polygons increment pixel stencil buffer count zero • increment when depth test passes – “Render” back faces of shadow volumes • Turn off color, depth updates (but leave depth test on) • Visible polygons decrement pixel stencil buffer count • decrement when depth test passes +2 +2 – Render scene with only diffuse/spec lighting Eye +1 • Only update pixels where stencil = 0 +3 • Others are in shadow (ambient only)! position

Illuminated, Shadowed, Nested in Shadow Behind Shadow Volumes (Zpass) Volumes (Zpass)

Light Shadowing object Light Shadowing object source source

zero +1 zero +1

zero zero

+ + + - - - Unshadowed + + + - object +2 +2 +2 +2 Shadowed Eye +1 Eye +1 object +3 +3 position position

Shadow Volume Count = +1+1+1-1-1-1 = 0 Shadow Volume Count = +1+1+1-1 = 2

Illuminated, In Front of Shadow Problems Created by Volumes (Zpass) Near Clip Plane (Zpass)

Missed shadow volume intersection due to near clip plane clipping; leads Light Shadowing object to mistaken count Far clip source plane zero zero +1 +1 +1 zero +2 zero +3 +2 +2 +2 Unshadowed Eye +1 object +3 Near clip position plane Shadow Volume Count = 0 (no depth tests pass)

5 Shadow Volumes (Zfail) Zfail versus Zpass Comparison

• Details of the basic algorithm: • When stencil increment/decrements occur – Compute shadow volumes • View-independent! – Zpass: on depth test pass – Clear stencil buffer – Zfail: on depth test fail – Render the scene without diffuse/spec lighting • Sets the Depth Buffer and Color Buffer • Increment on – “Render” back faces of shadow volumes – Zpass: front faces • Turn off color, depth updates (but leave depth test on) • Visible polygons increment pixel stencil buffer count – Zfail: back faces • increment when depth test fails • Decrement on – “Render” front faces of shadow volumes • Turn off color, depth updates (but leave depth test on) – Zpass: back faces • Visible polygons decrement pixel stencil buffer count – Zfail: front faces • decrement when depth test fails – Render scene with only diffuse/spec lighting • Only update pixels where stencil = 0 • Others are in shadow (ambient only)!

Illuminated, Shadowed, Nested in Behind Shadow Volumes (Zfail) Shadow Volumes (Zfail)

Light Light Shadowing object Shadowing object source source

zero +1 zero +1

zero zero

Unshadowed + + object +2 +2 +2 +2 Shadowed Eye +1 Eye +1 object +3 +3 position position

Shadow Volume Count = 0 (zero depth tests fail) Shadow Volume Count = +1+1 = 2

Illuminated, In Front of Shadow Volumes (Zfail) Zfail versus Zpass Comparison

• Both cases order passes based stencil operation – First, render increment pass Light Shadowing object source – Second, render decrement pass – Why? zero +1 . Because standard stencil operations saturate . Wrapping stencil operations can avoid this zero • Which clip plane creates a problem - - - + + + – Zpass: near clip plane – Zfail: far clip plane +2 +2 Unshadowed Eye +1 object • Either way is foiled by view frustum clipping +3 position – Which clip plane (front or back) changes Shadow Volume Count = -1-1-1+1+1+1 = 0

6 Nested Shadow Volumes Stencil Counts Beyond One Amount of pixel processing

Shadowed scene Stencil buffer contents

green = stencil value of 0 red = stencil value of 1 Adapted from [Chan and Durand 2004] darker reds = stencil value > 1

Scene’s Visible Shadows in a Real Game Scene Geometric Complexity

Wireframe shows geometric complexity of Abducted game visible geometry images courtesy Joe Riedel at Contraband Entertainment

Primary light source location

Scene’s Shadow Volume Blow-up of Shadow Detail Geometric Complexity

Wireframe shows Notice cable geometric shadows on complexity of player model shadow volume geometry

Shadow volume geometry projects Notice player’s away from the own shadow on light source floor

7 Visible Geometry vs. Shadow Volume Geometry Other Example Scenes (1 of 2)

<< Visible geometry

Visible geometry Shadow volume geometry

Typically, shadow volumes generate Dramatic chase scene with shadows Shadow volume considerably more pixel updates than geometry visible geometry Abducted game images courtesy Joe Riedel at Contraband Entertainment

Other Example Scenes (2 of 2) Shadow Volumes Too Expensive

Visible geometry Chain-link fence is shadow volume nightmare!

Chain-link fence’s shadow appears on Shadow volume truck & ground with Scene with multiple light sources shadow maps geometry Abducted game images courtesy Joe Riedel at Contraband Entertainment Fuel game image courtesy Nathan d’Obrenan at Firetoad Software

Shadow Volume Advantages Shadow Volume Disadvantages

• Omni-directional approach • Ideal light sources only – Not just spotlight frustums as with shadow maps – Limited to local point and directional lights • Automatic self-shadowing – No area light sources for soft shadows • Requires polygonal models with connectivity – Everything can shadow everything, including self – Models must be closed (2-manifold) – Without shadow acne artifacts as with shadow maps – Models must be free of non-planar polygons • Window-space shadow determination • Silhouette computations are required – Shadows accurate to a pixel – Can burden CPU – Or sub-pixel if multisampling is available – Particularly for dynamic scenes • Required stencil buffer broadly supported today • Inherently multi-pass algorithm – OpenGL support since version 1.0 (1991) • Consumes lots of GPU fill rate – Direct3D support since DX6 (1998)

8 Shadows: Volumes vs. Maps Issues with Shadow Volumes

• Shadow mapping via projective texturing – The other prominent hardware-accelerated shadow technique – Standard part of OpenGL 1.4

• Shadow mapping advantages FF – Requires no explicit knowledge of object geometry – No 2-manifold requirements, etc. – View independent • Shadow mapping disadvantages – Sampling artifacts BF – Not omni-directional

Stencil Shadow Pros Stencil Shadow Cons

• Very accurate and robust • Too accurate — hard edges • Nearly artifact-free – Need a way to soften – Faceting near the silhouette edges • Very fill-intensive is the only problem – Scissor and depth bounds test help • Work for point lights and directional lights • Significant CPU work required equally well – Silhouette determination • Low memory usage – Building shadow volumes

Stenciled Shadow Volume Hardware Support Optimizations (1)

• GL_EXT_stencil_two_side •Use GL_QUAD_STRIP rather than GL_QUADS to • GL_ATI_separate_stencil_func render extruded shadow volume quads – Requires determining possible silhouette loop connectivity – Both allow different stencil operations to be •Mix Zfail and Zpass techniques executed for front and back facing polygons – Pick a single formulation for each shadow volume • GL_EXT_depth_bounds_test – Zpass is more efficient since shadow volume does not need to be closed – Helps reduce frame buffer writes – Mixing has no effect on net shadow depth count • Double-speed rendering – Zfail can be used in the hard cases

9 Stenciled Shadow Volume Stenciled Shadow Volume Optimizations (2) Optimizations (3)

• Pre-compute or re-use cache shadow volume • Take advantage of ad-hoc knowledge of scenes geometry when geometric relationship between a light whenever possible and occluder does not change between frames – Example: A totally closed room means you do not have to – Example: Headlights on a car have a static shadow volume cast shadow volumes for the wall, floor, ceiling w.r.t. the car itself as an occluder • Limit shadows to important entities • Advanced shadow volume culling approaches – Example: Generate shadow volumes for monsters and – Uses portals, Binary Space Partitioning trees, occlusion characters, but not static objects detection, and view frustum culling techniques to limit shadow – Characters can still cast shadows on static objects volumes • Mix shadow techniques where possible – Careful to make sure such optimizations – Use planar projected shadows or are truly correct light-maps where appropriate

Stenciled Shadow Volume Hardware Enhancements: Optimizations (4) Wrapping Stencil Operations • Shadow volume’s extrusion for directional lights can be rendered with a GL_TRIANGLE_FAN • Conventional OpenGL 1.0 stencil operations – Directional light’s shadow volume always projects to a single – GL_INCR increments and clamps to 2N-1 point at infinity – GL_DECR decrements and clamps to zero • DirectX 6 introduced “wrapping” stencil operations • Exposed by OpenGL’s EXT_stencil_wrap extension – GL_INCR_WRAP_EXT increments modulo 2N – GL_DECR_WRAP_EXT decrements modulo 2N • Avoids saturation throwing off the shadow volume depth count – Still possible, though very rare, that 2N, N N Scene with Clip-space view of 22 , 32 , etc. can alias to zero directional light. shadow volume

Hardware Enhancements: Hardware Enhancements: Depth Clamp (1) Depth Clamp (2)

• What is depth clamping? • Advantage for stenciled shadow volumes – Boolean hardware enable/disable – With depth clamp, P (rather than Pinf) can be used with our – When enabled, disables the near & far clip planes robust stenciled shadow volume technique – Interpolate the window-space depth value – Marginal loss of depth precision re-gained – Clamps the interpolated depth value to – Orthographic projections can work with our technique with the depth range, i.e. [min(n,f),max(n,f)] depth clamping •Assuming glDepthRange(n,f); • NV_depth_clamp OpenGL extension – Geometry “behind” the far clip plane is still rendered – Easy to use • Depth value clamped to farthest Z glEnable(GL_DEPTH_CLAMP_NV); • Similar for near clip plane, as long as w>0, glDisable(GL_DEPTH_CLAMP_NV); except clamped to closest Z

10 Hardware Enhancements: Hardware Enhancements: Two-sided Stencil Testing (1) Two-sided Stencil Testing (2)

• Current stenciled shadow volumes required rendering glStencilMaskSeparate and shadow volume geometry twice glStencilOpSeparate (face, fail, zfail, zpass) – First, rasterizing front-facing geometry glStencilFuncSeparate (face, func, ref, mask) – Second, rasterizing back-facing geometry – Control of front- and back-facing stencil state • Two-sided stencil testing requires only one pass update – Two sets of stencil state: front- and back-facing – Boolean enable for two-sided stencil testing Now part of OpenGL – When enabled, back-facing stencil state is used for stencil testing back-facing polygons – Otherwise, front-facing stencil state is used – Rasterizes just as many fragments, but more efficient for CPU & GPU

Performance Slide Credits

• Have to render lots of huge polygons • Cass Everitt & Mark Kilgard, NVidia – Front face increment – Back face decrement – GDC 2003 presentation – Possible capping pass • Timo Aila, Helsinki U. Technology • Burns fill rate like crazy • Turn off depth and color write, though • Jeff Russell • Gives accurate shadows – IF implemented correctly • David Luebke, University of Virginia – When fails, REALLY fails • Michael McCool, University of Waterloo • Need access to geometry if want to use silhouette optimization • Eric Lengyel, Naughty Dog Games

These are extra slides

• Hacks to further improve shadow volumes

11 Scissor Optimizations Scissor Optimizations

• Most important fill-rate optimization for • Scissor rectangle can be applied stencil shadows on a per-light basis or even a • Even more important for penumbral wedge per-geometry basis shadows • Requires that lights have a finite volume of • Hardware does not generate fragments influence outside the scissor rectangle — very fast – What type of light is this?

Light Scissor Light Scissor

Light • Project light volume onto the image plane

View Frustum • Intersect extents with the viewport to get light’s scissor rectangle • Mathematical details at: – http://www.gamasutra.com/features/ 20021011/lengyel_01.htm Image Plane

Camera

No Light Scissor Depth Bounds Test

Shadow volumes extend to edges of viewport Light Max Depth

Min Depth Light Scissor

Shadow volume fill View Frustum reduced significantly Camera

12 Depth Bounds Test Depth Bounds Test

• Like a z scissor, but... • Operates on values already in the depth Max Depth buffer, not the depth of the incoming Rejected fragment Fragments Shadow • Saves writes to the stencil buffer when Volume shadow-receiving geometry is out of range

Min Depth Camera Shadow Receiver

No Depth Bounds Test No Depth Bounds Test

Shadow volumes extend A lot of extra shadow closer to and further volume fill where we from camera than know it can’t have any necessary effect

Depth Bounds Test Depth Bounds Test

Shadow volume fill Parts that can’t outside depth bounds possibly intersect the is removed environment removed

Depth Bounds Test Depth Bounds Test

• Depths bounds specified in viewport • Let P be the projection matrix and let [dmin, coordinates dmax] be the depth range • To get these from camera space, we need • Viewport depth d corresponding to camera to apply projection matrix and viewport space z is given by transformation • Apply to points (0,0,z,1) ddPzPddmax min 33 34 max  min d  22Pz43 P 44

13 Geometry Scissor Geometry Scissor

• We can do much better than a single • Define a bounding box for the light scissor rectangle per light – Doesn’t need to contain the entire sphere of • Calculate a scissor rectangle for each influence, just all geometry that can receive geometry casting a shadow shadows – For indoor scenes, the bounding box is usually determined by the locations of walls

Geometry Scissor Geometry Scissor

• For each geometry, define a simple Light Sphere bounding polyhedron for its shadow volume – Construct a pyramid with its apex at the light’s position and its base far enough away to be outside the light’s sphere of influence Bounding – Want pyramid to be as tight as possible Box around geometry

Geometry Scissor Geometry Scissor

• Clip shadow volume’s bounding polyhedron to light’s bounding box Shadow • Project vertices of resulting polyhedron Volume Light Bounding onto image plane Sphere Polyhedron • This produces the boundary of a much smaller scissor rectangle

Light’s • Also gives us a much smaller depth Bounding bounds range Box

14 Geometry Scissor Geometry Scissor

Depth Clipped Bounds Light Bounding Sphere Polyhedron Scissor Rectangle

Light’s Bounding Image Plane Box Camera

Geometry Scissor No Geometry Scissor

Light scissor rectangle and depth bounds test are no help at all in this case Depth Bounds Geometry Scissor Scissor Shadow volume fill drastically reduced Image Plane

Camera

Scissor and Depth Bounds Scissor and Depth Bounds

• Performance increase for ordinary stencil • For penumbral wedge rendering, it’s a shadows not spectacular different story • Real-world scenes get about 5-8% faster • We will do much more work per fragment, using per-geometry scissor and depth so eliminating a lot of fragments really bounds test helps • Hardware is doing very little work per • Real-world scenes can get 40-45% faster fragment, so reducing number of using per-geometry scissor and depth fragments is not a huge win bounds test

15