I implemented this during a weekend, mostly because relief mapping has always interested me. Decided to toss in parallax mapping as well when I was “in the neighborhood”, and a little normal mapping for good measure as well. This is the basic implementation of both techniques with no optimizations or artifact corrections.
Here is a small code snippet. Nothing special, just don’t like to not show code.
float ray_intersect_relief(in float2 orig, in float2 dir)
{
const float max_num_linear_steps = 20;
const float max_num_binary_steps = 5;
float depth = 0.0f;
float size = 1.0f / max_num_linear_steps;
// Attempt to find the first intersection against the relief map with a linear search.
// This is because binary search can easily miss topography.
for(int i = 0; i < max_num_linear_steps - 1; i++)
{
float4 t = gTexRelief.Sample(textureSampler, orig + dir * depth);
if(depth < t.r)
depth += size;
}
// A binary search to try and find the "edge" of the closest intersection point
for(int j = 0; j < max_num_binary_steps; j++)
{
size *= 0.5f;
float4 t = gTexRelief.Sample(textureSampler, orig + dir * depth);
if(depth < t.r)
depth += 2*size;
depth -= size;
}
return depth;
}