## The deadline for giving back Practical 3 is: Friday, December 2nd (midnight, European Time)

There are two independent parts in this practical: Shadow mapping and Procedural textures with noise. You can do them in any order.

We render scenes with shadow maps in two steps:

• First, we render the scene as viewed from the light source, offscreen. We store the depth map of this rendering into the shadow map.
• Second, in the standard rendering, for each fragment, we compute its position in light space (as well as in screen space). We use this position in light space to access the shadow map, and compare the depth in light space with the depth in the shadow map:
• If the point being rendered is further away than the depth stored in the shadow map, then it is in shadow. We render it using only ambient lighting.
• If the depths are equal, then the point is lit. We render it using ambient, diffuse and specular lighting.

• In the C++ source file glshaderwindow.cpp, add the transforms that go from world space to the (projective) light space (it is near the point that says TODO_TP3 in the source code). You will need to pass these transformation matrices to the shader that computes the shadow map, h_shadowMap (this one is already written).
• You can check that the shadow map exists, and what it contains, by uncommenting the line debugPix.save("debug.png"); in the source. Check that the shadow map changes as you move the light source.
• In your shader, when you compute local illumination, you have to compute object coordinates both in camera space and in light space. You have already done the former (in Practical 1). For the latter, reuse the transformation matrices you used to compute the shadow map. Send them to the shader that is computing illumination.

In the vertex shader, apply both transforms to vertex coordinates, and store both results:

No bias With biais
    lightSpace = worldToLightSpace * worldCoords;
gl_Position = perspective * matrix * worldCoords;


In the fragment shader, use lightSpace both for:

• the distance from this point to the light source, lightSpace.z,
• texture coordinates in the shadow map, lightSpace.xy

As in the previous practical (with bump mapping), the coordinates you have after transform are in , while texture coordinates are in . You will have to rescale from one system to the other.

Don't forget that a projection matrix changes the w coordinate in homogeneous coordinates. You have to account for this in your code.

Start by computing shadow mapping without any bias in the depth comparison. You should get a picture that looks like the top picture (maybe with even more stripes). In a second stap, add the bias to the depth comparison. There are several bias methods: add epsilon, multiply by (1 + epsilon), take the slope into account, etc. Experiment with them, keep the one that seems to be most efficient / working for your test scenes.

Question: what happens when you query the shadow map beyond its boundaries? How can you detect is? What should you do? What should you do when w is negative?

## Procedural textures with noise

In the shader noiseAlone there is a function, perlinNoise. This function computes a Perlin noise, as a function of position.

It takes several parameters: the number of octaves, the amplitude, lacunarity and persistence. You can act on these parameters, depending on what you need.

 Low persistence High persistence