6.2.1 History of reflection implementations

Graphics developers have always tried to find computationally cheap methods to implement reflections.

One of the first solutions is spherical mapping. This technique simulates reflections or lighting on objects without using expensive ray-tracing or lighting calculations.
The following figure shows an environment map on a sphere:
Figure 6-9 Environment map on a sphere

The following figure shows the equation for mapping a spherical surface into two dimensions:
Figure 6-10 Spherical surface 2D mapping equation

This approach has several disadvantages, but the main problem is the distortions that occur when mapping a picture onto a sphere. In 1999, it became possible to use cubemaps with hardware acceleration. Cubemaps solved the problems of image distortions, viewpoint dependency and computational inefficiency related to spherical mapping.
The following figure shows an unfolded cube:
Figure 6-11 Unfolded cube

Cubemapping uses the six faces of a cube as the map shape. The environment is projected onto each side of a cube and stored as six square textures, or unfolded into six regions of a single texture. The cubemap is generated by rendering the scene from a given position with six different camera orientations with a 90 degree view frustum representing each a cube face. Source images are sampled directly. No distortion is introduced by resampling into an intermediate environment map.
The following figure shows infinite reflections:
Figure 6-12 Infinite reflections

To implement reflections based on cubemaps, evaluate the reflected vector `R` and use it to fetch the texel from the cubemap `_Cubemap` using the available texture lookup function `texCUBE()`:
`float4 color = texCUBE(_Cubemap, R);`
The normal `N` and view vector `D` are passed to fragment shader from the vertex shader. The fragment shader fetches the texture color from the cubemap:
```float3 R = reflect(D, N);
float4 color = texCUBE(_Cubemap, R);		```
This approach can only reproduce reflections correctly from a distant environment where the cubemap position is not relevant. This simple and effective technique is mainly used in outdoor lighting, for example, to add reflections of the sky.
The following figure shows incorrect reflections:
Figure 6-13 Incorrect reflections

If you use this technique in a local environment it produces inaccurate reflections. The reason why the reflections are incorrect is that in the expression `float4 color = texCUBE(_Cubemap, R);` there is no binding to the local geometry. For example, if you walk across a reflective floor looking at it from the same angle you always see the same reflection. The reflected vector is always the same and the expression always produces the same result. This is because the direction of the view vector does not change. In the real world reflections depend on both viewing angle and viewing position.