Opengl Shadow Mapping
Total Page:16
File Type:pdf, Size:1020Kb
What is Projective Texturing? • An intuition for projective texturing Shadow Mapping • The slide projector analogy in OpenGL Source: Wolfgang Heidrich [99] 2 About About Projective Texturing (1) Projective Texturing (2) • First, what is perspective-correct texturing? • So what is projective texturing? • Normal 2D texture mapping uses (s, t) coordinates • Now consider homogeneous texture coordinates • 2D perspective-correct texture mapping • (s, t, r, q) --> (s/q, t/q, r/q) • means (s, t) should be interpolated linearly in eye-space • Similar to homogeneous clip coordinates where • per-vertex compute s/w, t/w, and 1/w (x, y, z, w) = (x/w, y/w, z/w) • linearly interpolate these three parameters over polygon • Idea is to have (s/q, t/q, r/q) be projected per- • per-fragment compute s’ = (s/w) / (1/w) and t’ = (t/w) / (1/w) fragment • results in per-fragment perspective correct (s’, t’) • This requires a per-fragment divider • yikes, dividers in hardware are fairly expensive 3 4 About About Projective Texturing (3) Projective Texturing (4) • Hardware designer’s view of texturing • Tricking hardware into doing projective textures • Perspective-correct texturing is a practical • By interpolating q/w, hardware computes per- requirement fragment • otherwise, textures “swim” • (s/w) / (q/w) = s/q • perspective-correct texturing already requires • (t/w) / (q/w) = t/q the hardware expense of a per-fragment divider • Net result: projective texturing • Clever idea [Segal, et al. ‘92] • OpenGL specifies projective texturing • interpolate q/w instead of simply 1/w • only overhead is multiplying 1/w by q • so projective texturing is practically free if you • but this is per-vertex already do perspective-correct texturing! 5 6 1 Back to the Shadow Back to the Shadow Mapping Discussion . Fixed Function Mapping Discussion . Fixed Function • Assign light-space texture coordinates via texgen • Assign light-space texture coordinates via texgen • Transform eye-space (x, y, z, w) coordinates to • Transform eye-space (x, y, z, w) coordinates to the light’s view frustum (match how the light’s the light’s view frustum (match how the light’s depth map is generated) depth map is generated) • Further transform these coordinates to map • Further transform these coordinates to map directly into the light view’s depth map directly into the light view’s depth map • Expressible as a projective transform • Expressible as a projective transform • load this transform into the 4 eye linear plane • load this transform into the 4 eye linear plane equations for S, T, and Q coordinates equations for S, T, and Q coordinates • (s/q, t/q) will map to light’s depth map texture • (s/q, t/q) will map to light’s depth map texture 7 8 Tricks Tricks 9 10 Tricks Tricks 11 12 2 Tricks Tricks 13 14 Shadow Map Eye Linear Tricks Texgen Transform (Fixed Function) glTexGen automatically applies this when x x modelview matrix e Eye o y y contains just the eye view e = view Modeling o transform ze (look at) matrix zo matrix we wo s 1/2 1/2 Inverse x Light Light e eye t 1/2 1/2 frustum view ye view Need to scale/bias too! = (projection) (look at) r (look at) ze 1/21/2 matrix matrix q matrix we 1 15 Supply this combined transform to glTexGen 16 Setting Up Eye Linear Eye Linear Texgen (Fixed Function) Texgen Transform (Fixed Function) • With OpenGL • Plane equations form a projective transform GLfloat Splane[4], Tplane[4], Rplane[4], Qplane[4]; glTexGenfv(GL_S, GL_EYE_PLANE, Splane); glTexGenfv(GL_T, GL_EYE_PLANE, Tplane); glTexGenfv(GL_R, GL_EYE_PLANE, Rplane); glTexGenfv(GL_Q, GL_EYE_PLANE, Qplane); s Splane[0] Splane[1] Splane[2] Splane[3] x glEnable(GL_TEXTURE_GEN_S); e glEnable(GL_TEXTURE_GEN_T); t Tplane[0] Tplane[1] Tplane[2] Tplane[3] glEnable(GL_TEXTURE_GEN_R); = ye glEnable(GL_TEXTURE_GEN_Q); r Rplane[0] Rplane[1] Rplane[2] Rplane[3] ze • Each eye plane equation is transformed by current inverse q modelview matrix Qplane[0] Qplane[1] Qplane[2] Qplane[3] we • Very handy thing for us; otherwise, a pitfall • Note: texgen object planes are not transformed by the inverse modelview (MISTAKE IN REDBOOK!) • The 4 eye linear plane equations form a 4x4 matrix • No need for the texture matrix! 17 18 3 Shadow Map Tricks Operation • Automatic depth map lookups • After the eye linear texgen with the proper transform loaded • (s/q, t/q) is the fragment’s corresponding location within the light’s depth texture • r/q is the Z planar distance of the fragment relative to the light’s frustum, scaled and biased to [0,1] range Still Need to scale/bias! • Next compare texture value at (s/q, t/q) to value r/q • if texture[s/q, t/q] r/q then not shadowed • if texture[s/q, t/q] < r/q then shadowed 19 20 shadow Filtering Mode shadow API Usage • Performs the shadow test as a texture filtering operation • Shadow Map Samplers: • sampler2DShadow, sampler1DShadow, samplerCubeShadow • Looks up texel at (s/q, t/q) in a 2D texture • Request shadow map filtering with glTexParameter calls • Compares lookup value to r/q • glTexParameteri(GL_TEXTURE_2D, • If texel is greater than or equal to r/q, then GL_TEXTURE_COMPARE_MODE, generate 1.0 GL_COMPARE_REF_TO_TEXTURE); • Default is GL_NONE for normal filtering • If texel is less than r/q, then generate 0.0 • Only applies to depth textures • Modulate color with result • Also select the comparison function • Zero if fragment is shadowed or unchanged • Either GL_LEQUAL (default) or GL_GEQUAL color if not • glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); 21 22 New Depth Texture Hardware Shadow Internal Texture Formats Map Filtering • depth_texture supports textures containing depth values for shadow mapping • “Percentage Closer” filtering • Three internal formats • Normal texture filtering just averages color components • GL_DEPTH_COMPONENT16 • Averaging depth values does NOT work • GL_DEPTH_COMPONENT24 • Solution [Reeves, SIGGARPH 87] • GL_DEPTH_COMPONENT32 • Hardware performs comparison for each sample (same as 24-bit on GeForce3/4/Xbox) • Then, averages results of comparisons • Provides anti-aliasing at shadow map edges • Hint: use GL_DEPTH_COMPONENT for your texture internal format • Not soft shadows in the umbra/penumbra sense • Leaving off the “n” precision specifier tells the driver to match your depth buffer’s precision • Copy texture performance is optimum when depth buffer precision matches the depth texture precision 23 24 4 Hardware Shadow Map Mipmapping for Depth Textures with Filtering Example Percentage Closer Filtering (1) • Mipmap filtering works GL_NEAREST: blocky GL_LINEAR: antialiased edges • Averages the results of comparisons form the one or two mipmap levels sampled • You cannot use gluBuild2DMipmaps to construct depth texture mipmaps • because you cannot blend depth values! • If you do want mipmaps, the best approach is re-rendering the scene at each required resolution • Usually too expensive to be practical for all mipmap levels • Mipmaps can make it harder to find an appropriate polygon offset scale & bias that guarantee avoidance of self-shadowing Low shadow map resolution • You can get “8-tap” filtering by using (for example) two used to heightens filtering artifacts mipmap levels, 512x512 and 256x256, and setting your min 25 and max LOD clamp to 0.5 26 Advice for Shadowed The Need for Illumination Model (1) Dimming Diffuse No dimming; shadowed With dimming; shadowed • Typical illumination model with decal texture: regions have 0% diffuse regions have 40% diffuse ( ambient + diffuse ) * decal + specular and 0% specular and 0% specular The shadow map supplies a shadowing term • Assume shadow map supplies a shadowing term, shade • Percentage shadowed No specular • 100% = fully visible, 0% = fully shadowed in shadowed • Obvious updated illumination model for shadowing: regions in ( ambient + shade * diffuse ) * decal + shade * specular both versions. • Problem is real-world lights don’t 100% block diffuse shading on shadowed surfaces • Light scatters; real-world lights are not ideal points Front facing shadowed Still evidence of curvature regions appear unnaturally flat. in shadowed regions. 27 28 Advice for Shadowed Careful about Illumination Model (2) Back Projecting Shadow Maps (1) • Illumination model with dimming: • Just like standard projective textures, shadow ( ambient + diffuseShade * diffuse ) * decal + specular * shade maps can back-project where diffuseShade is Pentagon diffuseShade = dimming + ( 1.0 – dimming ) * shade would be Spotlight casting shadow incorrectly (a hooded light source) Easy to implement with fragment shaders lit by back- • Separate specular keeps the diffuse & specular lighting results projection distinct if not specially handled Back-projection of spotlight’s cone of illumination Spotlight’s cone of illumination 29 where “true” shadows can form 30 5 Careful about Combining Shadow Mapping Back Projecting Shadow Maps (2) with other Techniques • Techniques to eliminate back-projection: • Good in combination with techniques • Modulate shadow map result with lighting result from a single • Use stencil to tag pixels as inside or outside of shadow per-vertex spotlight with the proper cut off (ensures light is “off” • Use other rendering techniques in extra passes behind the spotlight) • bump mapping • Use a small 1D texture where “s” is planar distance from the • texture decals, etc. light (generate “s” with a planar texgen mode), then 1D texture is • Shadow mapping can be integrated into more complex multi- 0.0 for negative distances and 1.0 for positive distances. pass rendering algorithms •