Ray Marching

Overview

Ray marching with distance fields can be used to display complex three-dimensional scenes in the fragment shader. Traditional ray marching can use constant or variable step size to collect and render volumetric data. Signed distance fields are global functions describing the shortest distance to a shape. In a scene with multiple geometries, the minimum absolute value of all fields can be used as a safe maximum step size for a ray to travel without intersecting any geometries. This project is based on the work of Inigo Quilez and the demos posted on Shadertoy.

The main work is done in the fragment shader where, for each pixel, a ray is cast in the camera view direction and marched forward by the distance field values at their endpoints until they arrive at a surface or reach a maximum distance. By recording where a ray comes to a stop, we can determine which object is visible for a pixel. The normal of the object at the ray-surface intersection point can be found from the gradient of the distance field by sampling the value in the immediate vicinity. The normal is then used to determine surface colour from lighting and reflections. Shadowing is straightforward to find by marching another ray from the initial intersection towards a light source and determining if there is anything in the way. Soft shadows are rendered by using the global distance field to record how close the shadow ray comes to another object. Ambient occlusion can be rendered in the same manner by travelling outward from a surface in the normal direction and looking for occluding objects.

The armillary rings are constructed from the intersection of a sphere and a torus. The blob geometry demonstrates a smooth union operator applied to the distance fields and colours of multiple spheres. The sky is a simple colour gradient and the checkered floor is based on examples found on Shadertoy.