Project : Water Surface and Rendering (GPU Shader, CUDA and Raytracing)

Water is common seen in daily life. However, the interaction and rendering of water involve complex physical computation. In this work, we would like you to explore a few possibility to simulate the water surface and render the surface with shader programs and CUDA programs which become more and more important in graphics.


The Basic Task

With the advance of GPU technology, GPU becomes more and more popular in computer graphics specially in game industry. It is also noticed by general computation community. Water surfaces are common in computer graphics, especially in games for creating fantastic effects. They are a critical element that can significantly improve the level of realism in a scene. But depicting them realistically is a hard problem, because of the high visual complexity present in the motion of water surfaces, as well as in the way light interacts with water. This project would give you the chance to explore techniques developed for rendering realistic depictions of the water surface. With these two things in mind, this project would like you to have the experience by implementing a shader program and a CUDA program to generate a water surface and then rendering it with reflection and refraction effects. In addition, ray-tracing is very important global illumination algorithm to generate realistic images in graphics community. Therefore, the project also ask you to implement a ray tracer for rendering the water and other scene objects.

The Tasks

Fundamentally, to generate the perception of the water in an interactive application consists of two tasks:

  1. Your program has to generate a water surface according to some physical rules which are formed for some specific phenomenon in your mind. This generated surface represents the boundary of water for a renderer to generate proper images for illustrating the water surface.
  2. Your program must render the water surface to simulate the effects of refraction and reflection. Furthermore, the caustics caused by water movement on the sea floor can be added to add more reality.

In addition, realistically rendering the water surface is also important for other graphics applications, a basic ray-tracing algorithm is required to simulate the global illumination effect in the scene. The ray tracer will generate an image according to rays through the center of all pixels to interact with the scene object and then compute the lighting effects and shadow effects.

Water surface generation with GPU

Basically, the water surface can be simply decomposed into two geometric components: high-level surface structure and low-level surface details.

  • The surface structure represent the large scales of the wave movement and can be represented with a set of 2D grid with the y direction represent the height of the grid point. A vertex shader can be used to simulate the movement at the vertices by changing the normal and the y position of the vertex.
  • The surface detail represent the small scale perturbation in the local area and generally can be represented as a normal map. A pixel shader is created to generate a normal map for those perturbation.

Generally, there are several ways to implement the wave on the surface of water:

  • Sine waves (20) (Ref. 1): The sum of the sine waves are chosen to represent the complex water surface movement. The equation can be expressed as


·       Wavelength (L): the crest-to-crest distance between waves in world space. Wavelength L relates to frequency w as w = 2w/L.

·       Amplitude (A): the height from the water plane to the wave crest.

·       Speed (S): the distance the crest moves forward per second. It is convenient to express speed as phase-constant, phi , where phi = S x 2w/L.

·       Direction (D ): the horizontal vector perpendicular to the wave front along which the crest travels. Please refer to Ref. 1 for more direction details.

  • Height maps (20) (Ref. 3): similar to sine wave method, height map method decomposes the wave on the water surfaces into a set of different level of detail represented as a heightmap (the shape of single component and generated by artists) The following shows an example of the height map.


The combination of the heightmap can be expressed as the following equation.


Please refer to Ref. 3 for more heightmap details.

  • Wave equation(Ref. 4): Generally, the movement of the wave can be expressed as a wave equation as listed in the following:


Then by modeling the water surface as cubic Bspline surfaces, the right hand side of the equation can be expressed by the following:


And then the integration can be computed with one of the following integration methods


Then the equation is solved at each vertex of the 2D mesh to generate the water surface. Please refer to Ref. 4 for details.

Water surface rendering with GPU

Two important effects for the water surface rendering: reflection and refraction. We assume that we are looking outside the water. The reflection and refraction can be generated with the following different methods

  • Combination of refraction and reflection with an environment map for the sky and a set of texture map for the box. (Ref. 1) (20)
  • Using the refraction map and reflection map to simulate the possible viewing condition from above the water to simulate the refraction and reflection effects. (Ref. 4) (25). The following shows an example of refraction and reflection map


In addition to the refraction and reflection, the caustics on the floor due to concentration of refraction and reflection is also visually important. Therefore, simulate the caustics effect on the floor is also important for the rendering. (20)Project4-Caustics-Example.png




Write a Raytracer for water

As we discussed in class, you must implement a simple raytracer that can render triangle meshes in OGRE3D. We will provide you a skeleton source code? to allow you to load in objects, move, scale and rotate the object in a Cornell box as shown in the following figure. There will be also a UI to add point light source and directional light source. The point light source will represent as a sphere and the directional light will be represented as an arrow. There will be a ray-tracing button for initializing the ray-tracing operation and the result will be written out and posted on the window in the right. There are also a few ui to specify the rendering process

  1. Resolution W and H.
  2. Point and directional light sources.

Your raytracer must handle shadows. It should be as modular as possible in design, with reflectance models separated from geometry. Later, we will build upon this assignment to explore other aspects of high quality rendering, such as form factor computations for radiosity, and advanced reflectance models. You might also want to use it for your project. The implementation should consists of the following steps

  1. After clicking the ray-tracing button, the water surface should be exported to a texture as heightmap.
  2. Your program will generate a mesh from the heightmap.
  3. The ray tracer will start to trace rays through the world to render the view.

The following is the scores for this parts:

  1. Generate the water surface (10)
  2. Generating Camera Rays (10): Write code to generate camera rays using a camera specification based on a look-at vector, an up-vector, a vertical field of view, and an image aspect ratio. Your code should be able to handle arbitrary image resolutions.
  3. Shapes and Ray-Surface Intersection
    1. Intersection(10): Extend the triangle class by implementing ray-triangle intersection. Write code to compute the surface normal at the intersection point.
    2. Shading(10): Implement a material that contains diuse, specular, and ambient terms. The material parameters should include coefficients that modulate diffuse, specular and ambient reflectance, and the Phong exponent. The material should be able to deal with multiple point lights.
    3. Shadows(5): Implement shadow rays to render shadows.
    4. Reflection(10): Extend your material model to include specular reflection. You will need to cast

rays recursively to follow the reflected light path.

1.     Refraction(5): Add specular refraction to your material. Include Schlick’s approximation for

Fresnel reflection.

Test your implementation using the sphere, teapot, and bunny scenes from the class web site. Include a rendered image that demonstrates the solution of each problem. Please name the images accordingly. Send all files in a compressed archive to before the deadline. We will compile a gallery of the best images from each assignment and show it on the class web site. From each assignment, we will choose an outstanding image whose author will have the chance to present it in class.

  1. Extra credit 1: extend to implement the distributed ray tracing.
  2. Extra credit 2: implement the ray-tracer with Optix.
  3. Extra credit 3: using PBRT ray-tracer to render the image.
What to hand in?

As usual, you must hand in everything needed to build and run your program, including all texture files and other resources.

In your readme, please make sure to have the following (you can break it into seperate files if you prefer):

  • Instructions on how to use your program (in case we want to use it when you're not around)
  • Descriptions of what your program does to meet all of the minimum requirements.

You should make a subdirectory of the project directory called "Gallery." In this directory, please put a few JPG pictures of the best scenes in your town. Please name the pictures login-X.jpg (where X is a number). Put a text file in the directory with captions for the pictures. (note: to make pictures, use the screen print and then use some program to convert them to JPG). ?


許乃晟, Bath Room - 許乃晟


高鵬淵, Water Surface and Rendering -- 高鵬淵


楊承翰, Space Bathroom -- 楊承翰


郭鴻年, Water Surface and Rendering -- 郭鴻年


Shih-Hsuan Hung, Water Surface and Rendering -- 洪仕軒