A university project to develop a procedurally generated Martian landscape written entirely in Shaders using HLSL and RenderMonkey.
The terrain was generated by implementing a shader ray marching based ray caster, implemented within the pixel shader. Ray casting allows a ray to be cast through each pixel which we can then use in conjunction with ray marching, to define the resulting pixel colour based on the colour of the shape hit by the ray. Ray marching works by marching along the ray in steps until it finds an intersection. The intersection is a shape defined in an implicit form. The terrain is defined using a procedurally generated height map, which describes elevation of the surface at a given position.
The actual terrain is defined by creating a height map using a two dimensional Perlin noise function that returns a value dependent on the x and z coordinates of the current position. Different types of terrain can be produced by altering the number of noise functions used to compute the value (octaves) and the amplitude and frequency applied to each octave.
The Stonehenge like structure and floating object were implemented using the same ray marching techniques that were used to create the procedural terrain. In this case a set of distance functions were used that define the specified shapes, and constructive geometric methods joined the distance fields together.
By checking for the minimum value between the results of two distance functions, you can determine which of the two shapes are closest to the camera and therefore which should be drawn. In doing this repeatedly against each object in the scene, including the terrain a scene was produced that encompasses a union of implicit objects.
Fog, Sun and Shadows
Achieved by normalising the sun position vector and finding the dot product between the ray direction and the sun. Using an exponential you can define the size of the sun, small exponent values result in a larger sun due to the larger resulting value, compared with larger exponents. The resulting value is added to the final colour of the pixel, producing bright white colours in the centre, and fading as the resulting dot product between sun direction and ray direction tend towards zero.
Shadows were implemented into the scene by ray marching back through the scene from the position of an object, towards the light source, returning a value to be added to the diffuse light calculation based on a shadow contribution factor, shadow length, and value returned from distance field.
Using the equation f = 1 / e^ (density. distance) taking the resulting value and using it to determine the colour contribution of fog with respect to the current pixel’s colour through linear interpolation. As distance increases the fog contribution will become greater, producing a fog that gets thicker over distance.