In this project I worked on several variations in the parallax mapping technique. Parallax mapping is a technique that tries to give volume to a flat surface, by using a heightmap to offset the texel selection and a normal map to accordingly modify the lighting. The later can be generated from the heightmap.
I am going to briefly explain what each version is doing, but for a more thorough explanation that includes code snippets, I will redirect you to the content I read to learn about parallax mapping: Parallax Occlusion Mapping in GLSL
Normal mapping modifies only the lightning in an image. Instead of using the normal vector of the point at which it is computing the light intensity, it reads the normal vector from a preset normal maps corresponding location.
Do consider that in the example above, not only the shadows appear due to the normal mapping, but the light gets dimmer into the distance as well
Basic parallax mapping
Rather than simply getting the color from the point at which the object is hit, we check the corresponding height map and advance in the direction the ray was coming to take the color at a distance forward proportional at the depth of the current point. This method is the simplest variation and does not take into consideration at all the heights of the areas its traversing, which results in getting a result worse than the original when the slopes are too steep or our scalar depth multiplier is too high.
Steep parallax mapping
This version actually takes into consideration what the displacement of the original position is actually encountering, and works reacting to that in a step by step manner. Taking the direction the camera ray was comming, it moves a predefined amount forward and checks whether the current position is below the heightmap. If it is not, we repeat the process until it is. The precision is adjustable since the smaller the step is made, the more time it will take but the more accurate the result will be.
Oclusion parallax mapping
Both the Occlusion and Relief techniques are an addition to the Steep one. In this case, after stopping at the point that was below the heightmap, we take that and the previous points, and get the intersection between the line from one to the other and line line from ones height in the heighmap and the other. This is a fast approximation that significantly enhances the precision.
The difference in the shadowing respect to Steep is not due to the method but because self shadowing is being done in these images.
Relief parallax mapping
In this other case, it goes all out for precision, losing a lot more in performance. After we have the point from Steep method, it takes the previous one and starts a binary search, performing a predefined amount of steps and taking the last point as a result.
Once the corresponding point has been selected using parallax mapping, a ray is cast from the point towards the light/lights. Every x distance a check is performed of how deep under the heightmap the point is (if it is at all), and then multiplied by a value inversely proportional to the distance to the original point. That is the shadow intensity. When the process is finished (the surface or texture real level is actually reached) the highest shadow intensity is conserved.