Adventures in GPU Programming - Warp
Tala Huhe (thuhe)The goal of this project was to explore noise functions as well as tesselation on the GPU. Combining them together along with a simple post-processing effect, I was able to obtain a very trippy demo.
Noise
In order to generate noise, I used this nice library. In particular, I used the 4D Simplex noise functions in order to obtain smooth, continuous noise. I was then able to visualize this noise by parametrizing it based on on-screen coordinates, time, and varying factors for each color.

Tesselation
Tesselation was fairly straightforward. I started with a regular icosahedron and tesselated the surface until I reached a sphere.

Afterwards, I peturb the surface based on the aforementioned Simplex noise function, parametrized on vertex location and time. In order to compute per-vertex normals for the new surface, I first compute three nearby neighbors by traversing towards each vertex of the original, untesselated triangle by a small epsilon. I then peturb these neighbors and compute the three gradient vectors along the surface of the final surface. Lastly, I cross each pair of these normals to obtain an estimate of the normal, and average the three values together.

To make the surface more visually interesting, I color the surface of the model based on height from the original sphere. I also add in a Phong lighting and shading model. Finally, I parametrize color and height based on time for some animation.

Varying the parameters caused very...interesting effects.

During this step, I also hack an ambient occlusion term. Since we are just peturbing vertices off a sphere, we can just measure how much a vertex protrudes from its local neighborhood and use it as an AO factor.

Due to the shifting colors, this effect is not quite noticable from screencaps; it becomes more apparent with a more constant color map. Below, I have colored each vertex by its normal and added the AO map. Note the dark spots in the troughs and dark bands going perpendicular across the saddles.


Post-Processing
I create a very simple depth-of-field effect by applying a box blur as a function of distance to focal plane. To make this effect more noticable, I added multiple primitives. In order to boost performance, I added dynamic LOD to my tesselator as a function of camera distance and screen size.

Controls
Here are the controls for the demo:
- W, A, S, D, Shift, Left Ctrl: Move the camera eye.
- Mouse: Adjust the camera heading.
- Tab: Toggle 2D/3D visualization.
- V: Toggle animation.
- B: Toggle ambient occlusion.
- N: Toggle Phong lighting model.
- M: Toggle normal map visualization.
- Comma: Toggle wireframe.
- Period: Toggle depth-of-field.
- Forward Slash: Toggle Justin mode.
- Right Shift: Toggle one/many primitives.