shadow mapping rtr team 2009 0. 1 why shadows? 2 rtr team 2009

31
Shadow Mapping RTR Team 2009 1

Post on 21-Dec-2015

216 views

Category:

Documents


0 download

TRANSCRIPT

Shadow Mapping

RTR Team 2009 1

RTR Team 2009 2

Why Shadows?

3

Why Shadows?

RTR Team 2009

4

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

RTR Team 2009

5

Shadow Determination

Several techniques, e.g.Shadow Mapping

Shadow Volumes

Let’s take a closer look at shadow mapping2 pass algorithm

fast on today’s GPUs

relatively easy to implement

RTR Team 2009

6

Shadow Mapping Overview

1st pass:we assume the light source has a “view frustum” just like a camerarender scene from light source’s positionsave depth values onlywe end up with a shadow (depth-) map

2nd pass:render scene as usual, but transform vertices to light space, toofor 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!!!RTR Team 2009

7

Scene – “Meta” View

EyeLight Source

RTR Team 2009

8

Scene – Light Source View

RTR Team 2009

9

Scene – Light Source View (Depth Only)

RTR Team 2009

10

Scene – Eye View

RTR Team 2009

11

Shadowed Fragment

Eye View

“Meta“ View

RTR Team 2009

12

Shadowed Fragment

“Meta“ View

Fragment DistanceDistance

from Shadow

Map

Eye View

RTR Team 2009

13

Lit Fragment

“Meta“ View

Eye View

RTR Team 2009

14

Lit Fragment

“Meta“ View

Fragment Distance Distancefrom

ShadowMap

RTR Team 2009

Eye View

15

Coordinate Systems

Eye Light World

Model

RTR Team 2009

16

Coordinate Systems

Eye

Light

World

Model

RTR Team 2009

17

Transforming to World Space

Eye

Light

World

Model

RTR Team 2009

18

Transforming to Light Space

Eye

Light

World

Model

Light (Vlight)

rendering from the light source‘s point of view

RTR Team 2009

19

Transforming to Eye Space

Eye

Light

World

Model

rendering from the eye‘s point of view

RTR Team 2009

20

1st pass: Create Shadow Map

Create an FBO

// create the texture we'll use for the shadowmapglGenTextures(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);

// create the texture we'll use for the shadowmapglGenTextures(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);

RTR Team 2009

21

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.

RTR Team 2009

22

2nd pass: Render from Eye’s POV

Transform vertices to eye space and project as usual

p‘ = Pcam * Vcam * M * p

RTR Team 2009

23

2nd pass: Render from Eye’s POV

Also transform vertices to light space and projectone 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

RTR Team 2009

24

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

RTR Team 2009

Shadow Mapping: Vertex Shader

texture_matrix = (Mtranslate*Mscale*Plight*Vlight*Vcam-1)

#version 140uniform mat4 M; // model matrixuniform mat4 V_cam; // view matrix for the camerauniform mat4 P_cam; // projection matrix for the camerauniform mat4 texture_matrix;

in vec4 vertex; // from the applicationout vec4 SM_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;}

#version 140uniform mat4 M; // model matrixuniform mat4 V_cam; // view matrix for the camerauniform mat4 P_cam; // projection matrix for the camerauniform mat4 texture_matrix;

in vec4 vertex; // from the applicationout vec4 SM_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;}

25RTR Team 2009

Shadow Mapping: Fragment Shader

Fragment Shader:

#version 140uniform sampler2D shadow_map;

in vec4 SM_tex_coord; // passed on from VSout 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 ...}

#version 140uniform sampler2D shadow_map;

in vec4 SM_tex_coord; // passed on from VSout 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 ...}

26RTR Team 2009

Add Offset to polygons when rendering shadow map

Artifacts

glPolygonOffset(1.1, 4.0); // these values work wellglPolygonOffset(1.1, 4.0); // these values work well

27RTR Team 2009

Decrease ambient term

Filter shadow map ...

Artifacts

28RTR 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_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);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

29RTR Team 2009

Shadow Mapping: Fragment Shader

Fragment Shader for Hardware PCF:

#version 140uniform sampler2DShadow shadow_map;

in vec4 SM_tex_coord; // passed on from VSout vec4 fragment_color; // final fragment color destination

void main(void) {

float shadow = textureProj(shadow_map, SM_tex_coord); // do something with that value ...

}

#version 140uniform sampler2DShadow shadow_map;

in vec4 SM_tex_coord; // passed on from VSout vec4 fragment_color; // final fragment color destination

void main(void) {

float shadow = textureProj(shadow_map, SM_tex_coord); // do something with that value ...

}

30RTR Team 2009

References

www.opengl.org/registryhttp://www.opengl.org/registry/doc/glspec31undep.20090528.pdf

http://www.opengl.org/registry/doc/GLSLangSpec.Full.1.40.07.pdf

31RTR Team 2009