Reflective Shadow Maps: Part 1
Hi, Habr! I present to you the translation of the article "Reflective Shadow Maps" by Eric Polman.
Reflective Shadow Maps (RSM) (reflecting shadow maps) is an algorithm that extends the “simple” shadow map . The algorithm takes into account the light scattered after the first contact with the surface ( diffuse ). This means that in addition to direct lighting, you get indirect lighting. In this article I will analyze the algorithm from the official article to explain it humanly. I will also briefly talk about shadow mapping .
Shadow Mapping (SM) is a shadow generation algorithm. According to the algorithm, we store the distance from the light source to the object in the depth map. On Figure 1 shows an example of a depth map. It stores the distance (depth) for each pixel.
Figure 1: This image shows a depth map. The closer a pixel is, the brighter it is.
That way, when you have a depth map in terms of the source of the light, you then draw the scene in terms of the camera. To determine whether an object is lit, you check the distance from the light source to the object. If the distance to the object is greater than the value stored in the shadow map (depth), the object is in the shadow. This means that the object should not be lit. In Figure 2an example is shown. You perform these checks for each pixel.
Figure 2: The distance from the light source to the pixel in the shadow is greater than the distance stored in the shadow map.
Reflective Shadow Mapping
Now that you understand the basic concept of Shadow Mapping , we will continue with Reflective Shadow Mapping (RSM). This algorithm extends the functionality of “simple” shadow maps . In addition to the depth data , you also store the world-space (in the world coordinate system) position , world-space normals and flux (luminous flux). I will explain why you need this data.
In the RSM world-space position must be stored in order to determine the distance between the pixels. This is useful for calculating the attenuation of light. Light fades (becomes less concentrated) when a certain distance passes. The distance between two points in space is used to calculate the intensity of illumination.
The worlds (world-space) are used to calculate the reflection of light from the surface. In the case of RSM, they are also used to determine if a given pixel is a light source for another pixel. If the two normals almost coincide, they will not give each other a lot of reflected light.
Luminous Flux (luminous flux)
Flux is the light intensity of the light source. Its unit of measurement is lumen , a term that you can currently see on packages of light bulbs. The algorithm saves flux for each pixel while the shadow map is drawn. Flux is calculated by multiplying the light intensity by the reflectance. For directional light, you will get a uniformly lit image. For spot light, you also consider the angle of incidence. The attenuation and the receiving cosine (between the normal and the light vector) are not taken into account, since this is taken into account when you consider indirect illumination. This article will not cover the details. In figure 3Shows the texture for the spot light from the official article.
Figure 3: The four maps contained in the RSM are shown . From left to right: depth map, world-space positions, world-space normals, flux.
Now that the data has been generated (theoretically), it's time to apply it to the final image. When you draw the final image, you calculate the effect of each light source on each pixel. In addition to simply lighting pixels using light sources, now you are also using Reflective Shadow Map .
A naive approach to calculating the contribution of lighting is to go through all the texels in the RSM . You check if the light from the texel in the RSM does not reach the pixel you are counting. This is done using world-space positions and world-space normals. You calculate the direction from the world-space position in the RSM texelto pixel. Then you compare it with the normal using the scalar product of vectors. Any positive value means that the pixel must be lit using flux , which is stored in the RSM . Figure 4 demonstrates this algorithm.
Figure 4: Demonstrating the contribution of indirect illumination based on world-space positions and normals.
Shadow maps (and RSMs ) are inherently large (512x512 = 262144 pixels), so checking every texel is far from optimal. Instead, it is best to make a certain number of samples from the card. The number of samples depends on how powerful your hardware is. Lack of samples can produce artifacts such as stripes or flicker.
The texels that will most influence the result of lighting are closest to the calculated pixel. The sampling method that collects most samples near the pixel coordinates will give the best results. This method is called “importance sampling” . The official article describes that the sampling density decreases with the square of the distance from the pixel we are counting.
We also need to scale the intensity of the samples, taking into account the coefficient depending on the distance. This is due to the fact that texels located further, though they are sampled less often, but in reality they are influenced by the same amount of flux. Therefore, the far pixels need to increase the intensity to smooth out the inequality, while maintaining a small number of samples. On Figure 5 shows how this works.
Figure 5: Importance sampling. More samples are taken from the center and the samples are scaled by a factor based on their distance from the center point. Borrowed from an article about RSM .
В качестве точки (s,t) берется проекция текущего пикселя на shadow map. А координаты сэнмплинга относительно (s,t) рассчитываются заранее и передаются массивом в шейдер.
You must treat the sample as a point source of illumination. You use the flux value as the light color and only those lights that are opposite the pixel.
The official article describes in more detail about other optimizations of this algorithm, but I will stop there. The Screen-Space Interpolation section describes how you can increase performance, but I think for the beginning of importance, sampling will be enough.
In the second part, the RSM implementation will be presented .