Landscape Rendering

During the Introduction to Computer Graphics course in 2010 I teamed up with Christian Christoffersen to create a project about rendering outdoor landscapes in OpenEngine. The project was split so Christian created the sky dome, while I worked on the landscape, a heightmap, and the ocean. I have listed some of the techniques I used below.

Dynamic Level of Detail

To support large heightmaps, a level of detail scheme is required. Our heightmap was divided into smaller patches which would each be rendered independently of each other. The bounding boxes of the patches can be seen in the image below. Each patch’s level of detail would be determined by its distance to the camera.
To avoid vertex popping I choose to implement geo-morphing. Geo-morphing can be implemented entirely in the vertex shader at the cost of a few extra vertex attributes. This means that it would off-load our CPU of intense vertex processing and it only added minimal extra work for the GPU’s vertex shaders. The result can be seen in the video above at 0:36.

Terrain Boxes

Terrain Boxes

Bump mapping

To add even more complexity to the surface of the landscape without adding a ton of additional vertices I added bump mapping. On the images below a bumped and unbumped terrain can be seen. (Incidentally, bump mapping is also one of the main reasons that I would like to try a shader language with units attached to the variables, so I don’t accidentally multiply the normal by the transposed tangentToWorld matrix.)

Terrain Unbumped

Terrain Unbumped

Terrain Bumped

Terrain Bumped

Post Process Effects

Having seen some cool post process effects in GPU Gems, we wanted to add a post process framework to OpenEngine, which could be used in our Terrain project but would also easily enable us to add them to older projects. Some of the basic effects implemented in this framework is grayscale, film grain and a simple motion blur, by blurring the current and last blurred frame.

Grayscale

Grayscale

Film grain

Film grain

Motion Blur

Motion Blur

Glow or Screen Wide Blur

To give the terrain a light dreamy feel and fake an overlit scene I created a screen wide blur post process effect. Too keep it relatively lightweight the blurring was split into a two pass process by separable convolution. The effect itself is very tiny, but it does make the image smoother.

No glow

No glow

Glow

Glow

Depth of Field

Expanding on the Screen Wide Blur kernel we then proceeded to add a rough Depth of Field post process effect, which blurs a fragment with its neighboring fragments based on their difference in depth.

No depth of field

No depth of field

Depth of field

Depth of field

Ray Casting (Fog)

Finally after the project was done I added a basic voxel ray caster, which was made for a friends fluid simulator. To test it we tried adding some fog to the terrain.

Fog

Fog

Raycasted volume

Raycasted volume

Source Code

The source code to OpenEngine and the Terrain project can be obtained by following these steps in a terminal

  1. git clone git@github.com:oe-legacy/openengine.git
  2. cd openengine
  3. ./dist.py install proj:Terrain

To run the project do the following

  1. ./make.py
  2. ./build/terrain/terrain
References

Geo-Morphing by Daniel Wagner.
Bump Mapping on Wikipedia.
Water Shading by Michael Horsch.
Frustum Culling by Lighthouse3d.com.
Simple Post Process Effects.
Real-Time Glow in GPU Gems.