Steep parallax mapping with self shadowing

This recipe builds on the previous one, parallax mapping, so if you haven't already done so, you may want to review that recipe prior to reading this one.  

Steep parallax mapping is a technique, first published by Morgan McGuire and Max McGuire in 2005. It improves upon parallax mapping, producing much better results at the cost of more fragment shader work. Despite the additional cost, the algorithm is still well suited to real-time rendering on modern GPUs.  

The technique involves tracing the eye ray through the height map in discrete steps until a collision is found in order to more precisely determine the appropriate offset for the texture coordinate. Let's revisit the diagram from the previous recipe, but this time, we'll break up the height map into n discrete levels (indicated by the dashed lines):

As before, our goal is to offset the texture coordinates so that the surface is shaded based on the bump surface, not the true surface. The point P is the surface point on the polygon being rendered. We trace the view vector from point P to each level consecutively until we find a point that lies on or below the bump surface. In the following image, we'll find the point Q after three iterations.  

As in the previous recipe, we can derive the change in x and y for a single iteration using similar triangles (see the Parallax mapping recipe):

As before, the scale factor (S) is used to vary the influence of the effect and to scale it to texture space. n is the number of height levels.

Using this equation, we can step through the height levels, starting at P and following the view vector away from the camera. We continue until we find a point that lies on or below the surface of the height map. We then use the texture coordinate at that point for shading.  Essentially, we're implementing a very simple ray marcher in the fragment shader.

The results are impressive. The following image shows three versions of the same surface for comparison. On the left is the surface with normal map applied. The middle image is the same surface rendered with parallax mapping. The right-hand image is generated using steep parallax mapping. All three images use the same normal map, height map, geometry, and camera position. They are all rendered as a single quad (two triangles). Note how the steep parallax shows the varying height of each brick. The height of each brick was always included in the height map, but the parallax mapping technique didn't make it noticeable:

You may have noticed that the image on the right also includes shadows. Some bricks cast shadows onto other bricks. This is accomplished with a simple addition to the preceding technique. Once we find point Q, we march another ray in the direction of the light source.  If that ray collides with the surface, the point is in shadow and we shade with ambient lighting only. Otherwise, we shade the point normally. The following diagram illustrates this idea:

In the preceding diagram, point Q is in shadow and point T is not. In each case, we march the ray along the direction toward the light source (s). We evaluate the height map at each discrete height level. In the case of point Q, we find a point that lies below the bump surface, but for point T, all points lie above it. 

The ray marchine process is nearly identical to that described before for the view vector. We start at point Q and move along the ray toward the light. If we find a point that is below the surface, then the point is occluded from the light source. Otherwise, the point is shaded normally. We can use the same equation we used for marching the view vector, replacing the view vector with the vector toward the light source.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
13.58.121.214