350 likes | 538 Views
Shadow Mapping. Why Shadows?. Why Shadows?. 2. RTR Team 2009. Why Shadows?. Shadows ... ... make a scene look more three-dimensional ... tell us about the positions of objects relative to each other ... tell us where the light comes from ... should really be there . 3. RTR Team 2009.
E N D
Shadow Mapping RTR Team 2009
Why Shadows? RTR Team 2009
Why Shadows? 2 RTR Team 2009
Why Shadows? Shadows ... ... make a scene look more three-dimensional ... tell us about the positions of objects relative to each other ... tell us where the light comes from ... should really be there 3 RTR Team 2009
Shadow Determination Several techniques, e.g. Shadow Mapping Shadow Volumes Let’s take a closer look at shadow mapping 2 pass algorithm fast on today’s GPUs relatively easy to implement 4 RTR Team 2009
Shadow Mapping Overview 1st pass: we assume the light source has a “view frustum” just like a camera render scene from light source’s position save depth values only we end up with a shadow (depth-) map 2nd pass: render scene as usual, but transform vertices to light space, too for each fragment, compare rasterized fragment depth to previously stored depth (read it from shadow map) zfragment > zfrom_shadow_map => fragment lies in shadow both fragments must be in light space!!! 5 RTR Team 2009
Scene – “Meta” View Light Source Eye 6 RTR Team 2009
Scene – Light Source View 7 RTR Team 2009
Scene – Light Source View (Depth Only) 8 RTR Team 2009
Scene – Eye View 9 RTR Team 2009
Shadowed Fragment “Meta“ View Eye View 10 RTR Team 2009
Shadowed Fragment “Meta“ View Fragment Distance Distance from Shadow Map Eye View 11 RTR Team 2009
Lit Fragment “Meta“ View Eye View 12 RTR Team 2009
Lit Fragment “Meta“ View Fragment Distance Distance from Shadow Map Eye View 13 RTR Team 2009
Coordinate Systems World Light Eye Model 14 RTR Team 2009
Coordinate Systems World Eye Model Light 15 RTR Team 2009
Transforming to World Space World Eye Model Light 16 RTR Team 2009
Transforming to Light Space World Eye rendering from the light source‘s point of view Model Light Light (Vlight) 17 RTR Team 2009
Transforming to Eye Space World Eye rendering from the eye‘s point of view Model Light 18 RTR Team 2009
1st pass: Create Shadow Map Create an FBO • // create the texture we'll use for the shadowmap • glGenTextures(1, &shadow_tex_ID);glBindTexture(GL_TEXTURE_2D, shadow_tex_ID);glTexImage2D (GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, SM_width, SM_height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL); • glGenFramebuffers(1, &shadow_FBO); • glBindFramebuffer(GL_FRAMEBUFFER, shadow_FBO);glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, shadow_tex_ID, 0);glDrawBuffer(GL_NONE); // essential for depth-only FBOs!!! • glReadBuffer(GL_NONE); // essential for depth-only FBOs!!! • // then, just before renderingglBindFramebuffer(GL_FRAMEBUFFER, shadow_FBO); 19 RTR Team 2009
1st pass: Create Shadow Map The “view” matrix must be set to Vlight Note: No projection matrix used up to now! but light-”camera” involves another projection! Turn off all effects when rendering to the shadow map No textures, lighting, etc. 20 RTR Team 2009
2nd pass: Render from Eye’s POV Transform vertices to eye space and project as usual p‘ = Pcam * Vcam * M * p 21 RTR Team 2009
2nd pass: Render from Eye’s POV Also transform vertices to light space and project one possibility: Use Vcam-1, the inverse view matrix of the camera pproj_lightspace = (Plight * Vlight * Vcam-1) * Vcam * M * p save as texture coordinates for accessing shadow map Note: the light‘s projection matrix may be different from the eye‘s projection matrix 22 RTR Team 2009
2nd pass: Render from Eye’s POV one last issue... plightspace is in the interval [-1…..+1] shadow map coordinates in range [0….+1] scaling/translation necessary (*0.5, +0.5) SMtexcoords = (Mtranslate*Mscale*Plight*Vlight*Vcam-1)* Vcam * M * p 23 RTR Team 2009
Shadow Mapping: Vertex Shader texture_matrix = (Mtranslate*Mscale*Plight*Vlight*Vcam-1) #version 140 uniform mat4 M; // model matrix uniform mat4 V_cam; // view matrix for the camera uniform mat4 P_cam; // projection matrix for the camera uniform mat4 texture_matrix; in vec4 vertex;// from the application out vec4SM_tex_coord;// pass on to the FS void main(void) { // standard transformation gl_Position = P_cam * V_cam * M * vertex; // shadow texture coords in projected light space SM_tex_coord = texture_matrix * V_cam * M * vertex; } 24 RTR Team 2009
Shadow Mapping: Fragment Shader Fragment Shader: #version 140 uniform sampler2D shadow_map; in vec4SM_tex_coord;// passed on from VS out vec4 fragment_color;// final fragment color destination void main(void) { // note the perspective division! vec3 tex_coords = SM_tex_coord.xyz/SM_tex_coord.w; // read depth value from shadow map float depth = texture(shadow_map, tex_coords.xy).r; float inShadow = (depth < tex_coords.z) ? 1.0 : 0.0; // do something with that value ... } 25 RTR Team 2009
Add Offset to polygons when rendering shadow map Artifacts glPolygonOffset(1.1, 4.0); // these values work well 26 RTR Team 2009
Decrease ambient term Filter shadow map ... Artifacts 27 RTR Team 2009
GPU can do depth compare in hardware and also PCF! Filter shadow map glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 28 RTR Team 2009
Shadow Mapping: Fragment Shader Fragment Shader for Hardware PCF: #version 140 uniform sampler2DShadow shadow_map; in vec4SM_tex_coord;// passed on from VS out vec4 fragment_color;// final fragment color destination void main(void) { float shadow = textureProj(shadow_map, SM_tex_coord); // do something with that value ... } 29 RTR Team 2009
References • www.opengl.org/registry • http://www.opengl.org/registry/doc/glspec31undep.20090528.pdf • http://www.opengl.org/registry/doc/GLSLangSpec.Full.1.40.07.pdf RTR Team 2009