GAM532 DPS932 – Week 8 Texture Shadow Implementation Depth Texture Shadows Basics Render scene depth from each light Render Scene from main camera for each light Compare depth from light’s depth target to each fragment Binding Light Camera Values struct Light { float4 diffuse; float4 specular; float3 attenuation; float3 spot; }; Texture2D shadowTex : register(t0); SamplerState shadowSamp : register(s0); Render scene depth from each light Bind each shadow camera to a depth target (no color needed) Bind each depth target to a slot in the shader Bridging the Gap Main Camera’s View Space Rendering scene from the main camera Read from texture bound to shadow camera Shadow Camera’s Clip-To-Texture Space Must find a way to transform from one space to the next What We Need To Find FragPos * InvLightMat Main Camera’s View Space Fragment Position Shadow Camera’s View Space Fragment Position Main Camera’s View Space Fragment Position Main Camera’s View Space Light Transformation Inverse Inversion of Orthographic Matrices | 0 1 | 0 0 | -1 0 | -8 9 0 1 0 3 0 0 0 1 | | | | Origin Orthographic Matrix Inverse Translation + Identity Transpose Rotation Translation | | | | | | | | 1 0 0 0 1 0 0 0 1 8 -9 -3 0 0 0 1 | | | | Inverse Translation Matrix * 0 1 0 0 0 -1 0 | 0 0 0 | 1 0 0 | 0 0 1 | Inverse Rotational Matrix = | 0 0 -1 0 | | 1 0 0 0 | | 0 1 0 0 | | -9 -3 -8 1 | Inverse Orthographic Matrix From View Space to Clip Space struct Light { float4x4 shadowProjection; float4 diffuse; float4 specular; float3 attenuation; float3 spot; }; Texture2D shadowTex : register(t0); SamplerState shadowSamp : register(s0); Shadow Camera’s View Space Fragment Position Shadow Camera Projection Transformation FragPos * shadowProjection Clip Space To Texture Coordinate Screen Coordinates -1 [ 23 12 29 31 ] [ x/w y/w z/w w/w] [ 0.74 -0.39 0.94 ] X Y Depth -1 [ 0.74 -0.39 0.94 ] 1 1 U V Depth [ x/2+0.5 y/2+0.5 z ] 0 [ 0.74 -0.39 0.94 1 ] [ 0.87 0.31 0.94 ] 1 0 Shadow Camera’s Clip Space Fragment Position Screen Coordinates of Fragment with Depth 1 Texture Coordinates Texture Coordinates of Fragment with Depth Testing Depth Yes 0.87 [ 0.87 0.31 0.94 ] 0.31 U V Depth Texture Coordinates of Fragment with Depth Sample Depth from Shadow Texture Is sampled depth lower than the calculated depth of the fragment? No The light hit a different object first, shadow casted on fragment, fragment is not lit The light hit the surface of the object, no shadow casted on fragment, fragment is lit Adding All Lights Together Each light contributes to an object Shadows only block one light Single object can project many shadows + + = Final Result High Detail (texture limited) Dynamically changing Shadow Self Shadowing Translucency effects easily added Expensive (re-render scene for each light) Detail limited by texture size Point lights are very expensive to cast shadows from (6 renders per light) Shadow Texture Notes Point lights require up to 6 shadow textures to map out (don’t do it) Point and spot lights radiate light in many directions Directional lights work in one direct and require an orthographic camera Depth Fighting Shadow Acne Floating point precision issue 0.94534 > 0.94522 0.945341458 > 0.945341456 0.945341458458??? > 0.945341458458??? Shadow Acne No Acne 0.945341458458??? + 0.0000001 > 0.945341458458??? Alias Reduction float2 poissonDisk[4] = { float2(-0.94201624, -0.39906216), float2(0.94558609, -0.76890725), float2(-0.094184101, -0.92938870), float2(0.34495938, 0.29387760) ); for (int i=0; i<4; i++) { if(texture2D(shadowTex, shadow.xy + poissonDisk[i]/700.0).z<ShadowCoord.z-bias ){ visibility-=0.2; } } Texture resolution can cause aliasing Sampling adjacent texels and blending can soften shadows Graphics Section Complete Audio Next… To Do • Begin work on your enhancement • Begin work on OpenGL labs • Prepare for Mid-term (for real this time, I’m not pushing back again)