Sebastian Kümper

MS Informatics: Games-Engineering

Terrain Visualization in CUDA

Overview

This project was my Bachelor's Thesis which I extended during a Guided Research to improve the quality.

The task in my Bachelor's Thesis was to transfer an existing terrain visualization written in the Pixel shader to CUDA. This was my first real encounter with ray casting and voxel representation.

The terrain visualization could handle arbitrary detailed data and display it. More detail at Terrain Visualization. The terrain data is given as height fields. This data is split into equal parts - so called tiles - and a mipmap pyramid is built. A coarser level tile is built out four finer tiles, which quarters the resolution at each level. During the rendering, the detail level of the tile to display is given by its distance to the viewer. This results that tiles with a finer resolution are used near the viewer and tiles with a coarser resolution are used far away from the viewer. In the initial implementation, each tile was separately ray traced in the pixel shader to display the terrain. A bounding box was used in the vertex shader to limit the testing area.

Basic Shadows

For the CUDA implementation, I had to make a few changes. I know I couldn't compete with the fast pixel box overlap test in the vertex shader, so I used a quadtree to determine the correct tiles for the test. So I needed to send the whole tree to the graphics card and not only the tiles.

I created the initial shadows also with simple raycasting. I obtain the hitpoint with the terrain for every pixel. I use this position to start a new ray towards the light source, i.e. the sun. A problem I had to solve was that parts of the terrain that aren't visible may throw a shadow. But these nonvisible parts are normally culled to improve the performance. I implemented another culling test that doesn't omit any tiles that may throw a shadow on tiles that are visible. The result of the shadow was quite good, although they weren't really realistic. I improved this in my Guided Research.

Improved Shadows

The first thing I did in my Guided Research was examining real shadows of mountains to verify that my results are realistic. The most prevalent visible characteristic is the border of the shadow. I came to the conclusion that the softening of the shadow is mainly due to the size of the sun. So the shadow value is determined by how much of the sun is visible from a given terrain point.

In my final solution, I used a single ray to determine the shadow value. I exploited the height field by altering the ray direction. I only calculated the vertical occlusion of the sun and approximated the horizontal occlusion via mipmapping of the height field and bilinear filtering between the values. I started with a shadow ray that starts at the point of interest and points towards the lower end of the sun. Because we have a simple heightfield with no caves or bridge-like structures we can be sure that if this ray doesn't hit anything, the point of interest is completely lit. I trace this shadow ray. Each time the ray hit a height field element I check whether this height field element is high enough to completely occlude the sun. If not, the shadow value is stored, the top of the height field element is the new starting point of the ray and the direction is altered accordingly. The final shadow value is given by the stored shadow value or when the sun is completely occluded.

Finally, to give the result a more atmospheric look, I added realistic sky color that changes depending on the position of the sun. The color of the sky is calculated by a parameterized method and only needs to be calculated if the sun direction changes and can be stored in a texture. The average color of the whole sky defines the light color for the shadowed parts of the terrain. The color of the sun defines the color of the lit parts of the terrain.

This was my first real project, where I had to program on the graphics card. I got to learn the structure and ability of graphics cards and the things you have to take special care of. It was also the first time I programmed a raycaster and voxel structure, which was a very interesting thing to do.