CS 184: Computer Graphics and Imaging, Summer 2020

Final Project: Sea Wave Surface Simulator

Lexy Li(3033785746), Jane Zhang(3033360800)



Abstract

Impacted by the current pandemic, we have unprecedentedly sheltered in place for months. Life under Covid-19 has separated us from the gorgeous nature. Ocean waves, as one of the signature views for us to remember California, is the subject of our animation project. In this project, we will simulate ocean wave motions on a mesh surface, and apply texture mapping and shading on it in real-time.



Technical Approach

Part I: Wave Surface Mesh

1. Basic Code Structure

Moving forward from project 4, we added two new objects to represent waves and wave surfaces. The resulting classes are as following:

2.Position Update Algorithm

The basic idea of Gerstner Waves is that each vertex position on the surface is the sum of all frequency(cosine) curves at this point at a specific time. We have decided to apply Gerstner's way of computing vertex normals and tangents instead of simply using mesh geometry. After careful testing, we believe that this new approach will give us a more natural shading effect later when we complete shader programs.

Position Update:
Vertex Normal:
Vertex Tangent:
where
frequency w = 2 / Wavelength L,
A = Amplitude,
Q = steepness,


3. Results



Part II: Real-time Rendering

1. Time-Tracking Algorithm:

After we've implemented point position update, we add a time attributde to Cloth so that we can keep track of elapsed time and make the surface move dynamically. More specifically, we will update the time variable by adding delta_t to it each time we call Cloth::Simulate. To map a plastic layer onto the surface, we choose the ambience color to be dark blue and use the original phong shader for now. Since the wave surface is displaced horizontally, we adjusted the light posiiton to be (-0.5, -0.5, -2). Below are pictures of how the plastic surface varies according to different values of wave parameters.

Crest becomes steeper and less smooth as the steepness parameter increases:

Steepness = 0.2

Steepness = 0.3

Steepness = 0.4

The peak of waves becomes higher as we increase amplitude, which makes sense as we are using cosine function to simulate the wave dynamically. The peak of waves is very sensitive to the value of amplitude, so we decided to keep it between 0 and 0.05 and we'll mainly use 0.05 for the rest part:

Amplitude = 0.03

Amplitude = 0.08

Amplitude = 1

The crest-to-crest distance between waves in world space increases as wave length increases.

Wavelength = 0.2

Wavelength = 0.5

Wavelength = 0.7

The direction of the waves changes as we input different direction vectors.

Direction: (x = 1, y = 2)

Direction: (x = 1, y = 1)

Direction: (x = 2, y = 1)

2. GUI

In GUI, the user is able to set the following values: number of waves on the surface, steepness of the waves, all parameters of the first dominating wave. Waves exceeding the number of 1 will be generated using default parameter values. In the Cloth header file, we set the number of waves to be 5 at maximum. The default parameter values vary across different waves. We are not rendering more than 5 waves because we have observed that too many waves will destruct the flow of the wave surface.

Part III: Shaders

1. Reflection. We first try to reflect the skyview onto the wave surface by constructing a "sky box" using cubemap. To account for the fact that the sky is endlessly wide, for all 6 faces of the cubmap, we use the same seamless skyview image. With only reflection, the sea surface looks like a mirror. To make it look more natural, we decide to decrease the value of alpha to be 0.5 after rigorous testing.

The sky view used to frame the cubemap
before reflecting skyview


Water reflection of sky with alpha = 1
Water reflection of sky with alpha = 0.5

2. Refraction. To account for the refraction between water and air, we adopt ior(index of reflection) to be 1.33 and compute eta to be 1.0/1.33. The reflected ray is then calculated and used for tecture sampling.

before refraction
The water base we used in the cubemap
refraction with the new base
Refraction with alpha = 1

3. Combining water refraction and surfrace reflection of sky

In the previous part, we observe that if we only use refraction, the water body would appear to have very little depth. In order to interpolate between refraction and reflection, we test out the resulting surface with different scalars and decide to scale refraction by 0.15 before adding them together. Again we set the alpha to be 0.5 to take care of the water transparancy.

reflection before refraction
The water base we used in the cubemap
out_color = (0.15 * Refracted_color + reflected_color) with alpha = 0.5

4. Bumping and phong shading after updating normal and tangent vectors. We use a new heightmap on the Bumping shader to render small ripples on the wave surface.

Phong shading on a plain surface

heightmap

surface after we apply bumping

5. A great interpolation of all: Dynamic wave surface with bumping, reflection, refraction

Customized texture

Part IV: Problems We Had and Lessons We Learned

  • The greatest problem we found in this project is interpolating different shading and texture mapping effects. In previous projects, we had lighting and tecture mapping separately implemented. Yet in this project, because we want the resulting ocean surface to be as authentic as possilble, we would want to apply all the shaders on the same object. This really relies on how well we pick the scalars to do linear interpolation over all color values. As we find few practical resources about it, we decide to try out a bunch of candidate values and make our best choice by eyeballing and comparing the resulting animations.
  • One thing we found interesting about this project is that wave coefficients like speed and wavelength play a big role in how authentic our sea wave surface looks. Even a little change will cause huge difference on the resulting waves, which directly decides how real our work looks. A good simulation not only needs a good math model, but also carefully prescribed constants.


Results

Customized texture

Customized texture



Part IV: References

Gerstner Wave Algorithm

https://developer.nvidia.com/sites/all/modules/custom/gpugems/books/GPUGems/gpugems_ch01.html

Our main take away from this paper is that we are allowing different waves to have different parameter values. Even when we are setting default values, we take care to not make the UI customized values global, as well as not making all default waves exactly the same. The variation between different waves on the surface is crucial to simulating an authentic ocean surface as variance is inevitable in real life.

As we said in part2.2, our main deviation from the paper is that we are limiting the number of waves to be 5 at maximum. We are not rendering more than 5 waves because we have observed that too many waves will destruct the flow of the wave surface.



Part V: Contributions from each team member

Lexy Li focused on:

Mesh Construction, Code Structure Management, GUI, Texture Mapping, Slides and Writeup Text

Jane Zhang focused on:

Geometric Algorithm, Shaders, Image/GIF Rendering, Slide and Writeup Media

All other work equally splitted.