120 likes | 273 Views
UW Extension Certificate Program in Game Development 2 nd quarter: Advanced Graphics. Shadows. Goals. Understand the problem with “rendering” shadows Review the different methods to do it. The nature of shadows. Shadows don’t really exist They are just “missing light”
E N D
UW ExtensionCertificate Program inGame Development 2nd quarter:Advanced Graphics Shadows
Goals • Understand the problem with “rendering” shadows • Review the different methods to do it
The nature of shadows • Shadows don’t really exist • They are just “missing light” • Missing because another object occluded the light • Shadows are not necessarily cast by another object! • Your arm can cast a shadow over your body • This is called “self-shadowing” • Often games don’t bother doing this • Shadows are fuzzy around the edges • Shadows don’t accumulate • Two objects hiding the light at a point, looks the same as a single object
The problem with shadows • Shadows rarely add to gameplay • It’s easy to just ignore them • But they do add a feel of completeness to the scene • Shadows are an O(N2) problem • Every object can get shadowed by every other object • Also scaled up by the number of lights! • The computational scale of this problem is untenable • Something is going to give
Method #1: blob shadows • An amorphous & fuzzy dark splotch under an object • This is the easiest method • Forget the lights • Forget the O(N2) • Cast a single shadow on the floor and be done • Worry only about Z-fighting • Shadow won’t climb up the walls
Method #2: projective shadows • Cast by a single light • “Flatten” the object on the floor • Manipulate the world matrix to accomplish this • It needs to be a “degenerate” matrix: Y_column = 0 • Add a skew for more sideways shadows • Shadow shows the shape of the object • Skinned objects are ok • Paint it opaque black or use transparency with a stencil op to mask • Worry about Z-fighting too • Shadow won’t climb up the walls
Method #3: Shadow buffer • Cast by a single light • Render the entire scene’s depth values into a texture • From the point of view of the light! • This light’s view space is what we call light space • Then render the scene with shadows • Sample from this texture to find out if pixel is in shadow • Must calculate perspective correction in light space!
Shadow buffer pros • Supports self-shadowing • But easily riddled with artifacts • Crawling up the walls works great • Fuzziness uses PCF “Percentage Closest Filtering” • Or fancier methods like variance maps • Scales great: O(N)
Shadow buffer cons • Shadows can appear blocky (buffer pixels showing) • Adjust light’s projection matrix to manipulate perspective • PCF doesn’t eliminate this • Only one light is supported • Can use multiple shadow maps, but it gets expensive
Method #4: Shadow volume • Cast by a single light • Render the scene normally • Then render an extruded version of the shadow casters • Render front & back faces • Render into stencil buffer only • Stencil accumulates an even/odd marker • Shadowed pixels end up with odd markers • Finally, render full-screen quad to paint odd pixels with shadow • Transparency is ok
Shadow volume pros • Self-shadowing is supported • Artifacts can be avoided by manipulating the extrusion • Crawling up the walls works great • Shadows are pixel-perfect: no blockiness • Scales very well: O(N) • N is the number of shadow casters
Shadow volume cons • Shadows are too perfectly sharp (no fuzziness) • Can render multiple times in multi-tap fashion • But it gets expensive • Only one light • Can render multiple times • Multiple lights can share the full-screen pass • Workarounds require access to the stencil bytes