Ocean Rendering

Published February 18, 2011
Advertisement
Rendering of water in Outerra.

There are two types of waves mixed - open sea waves with the direction of wind (fixed for now), and shore waves (the surf) that orient themselves perpendicularly to the shore, appearing as the result of oscillating water volume that gets compressed with rising underwater terrain.

Open sea waves are simulated in a usual way by summing a bunch of trochoidal (Gerstner) waves with various frequencies over a 2D texture that is then tiled over the sea surface. Obviously, the texture should be seamlessly tileable, and that puts some constraints on possible frequencies of the waves. Basically, the wave should peak on each point of the grid. This can be satisfied by guaranteeing that the wave has an integral number of peaks in both u,v texture directions. Resulting wave frequency is then

f05503985bb8320e11d98f8dd797e21c.png

Other wave parameters depend on the frequency. Generally, wave amplitude should be kept below 1/20th of wave length, as larger ones would break.
Wave speed for deep waves can be computed using the wavelength ? as:

0faad608688cd6f019ff5951f416138b.png

Direction of waves can be determined by manipulating the amplitudes of generated wave, for example the directions that lie closer to the direction of wind can have larger amplitudes than the ones flowing in opposite direction. The opposite wave directions can be even suppressed completely, which may be usable e.g. for rivers.


Shore waves form as the terrain rises and water slows down, while the wave amplitude rises. These waves tend to be perpendicular to shore lines.

In order to make the beach waves we need to know the distance from particular point in water to shore. Additionally, a direction vector is needed to animate the foam.

Distance from shore is used as an argument to wave shape function, stored in a texture. This shape is again trochoidal, but to simulate a breaking wave the equation has been extended to a skewed trochodial wave by adding another parameter determining the skew. Here's how it affects the wave shape:

trochoid2.gif

The equation for skewed trochoidal wave is:

f5e240da7fb66c93138600de56c62cae.png
348b7112cd5edae5087ee6ff219274e5.png

Skew ?=1 gives a normal Gerstner wave.

Several differently skewed waves are precomputed in a small helper texture, and the algorithm chooses the right one depending on water depth.

shore.png


Distance map is computed for terrain tiles that contain a shore, i.e. those with maximum elevation above sea level and minimum elevation below it. Shader finds the nearest point of opposite type (above or below sea level) and outputs the distance. Resulting distance map is filtered to smooth it out.
Gradient vectors are computed by applying Sobel filter on the distance map.

gradient-f.jpg
Gradient field created from Gaussian filtered distance map

Both wave types are then added together. The beach waves are conditioned using another texture with mask changing in time so that they aren't continual all around the shore.

Water color is determined by several indirect parameters, most importantly by the absorption of color components under the water. For most of the screen shots shown here it was set to values of 7/30/70m for RGB colors, respectively. These values specify the distances at which the respective light components get reduced to approximately one third of their original value.

water-r7g30b70.jpgwater-r70g30b7.jpg

Red: 7m, Green: 30m, Blue: 70m, Scattering coef.: 0.005 -------------- Red: 70m, Green: 30m, Blue: 7m


Another parameter is a reflectivity coefficient that tells how much light is scattered towards the viewer. Interestingly, scattering effect in pure water is negligible in comparison with the effect of light absorption. Main contributor to the observed scattering effect is dissolved organic matter, followed by inorganic compounds. This also gives seas slightly different colors.

water-refl000.jpgwater-refl020.jpg
Scattering coefficient: 0.000 -------------------------------------- Scattering coefficient: 0.020


Here's a short video showing it all in motion.

[media]

[/media]



TODO
Water rendering is not yet finished, this should be considered a first version. Here's a list of things that will be enhanced:
  • Better effect for wave breaking. This will probably require additional geometry, maybe a tesselation shader could be used for that.
  • Animated foam
  • Enhanced wave spectrum - currently the spectrum is flat, which doesn't correspond to reality. Wave frequencies could be even generated adaptively, reflecting the detail needed for the viewer.
  • Fixing various errors - underwater lighting, waves against the horizon, lighting of objects on and under the water, LOD level switching ...
  • Support for other types of wave breaking
  • Integrating climate type support to the engine, that will allow different sea parameters across the world
  • UI for setting water parameters
  • Reflect the waves in physics for boats

A few of ocean sunset and underwater screenshots that were posted on the forums during the development.


icon-tw.pngOuterra on Twitter icon-fb.pngOuterra on Facebook
7 likes 14 comments

Comments

Giallanon
Amazing
February 18, 2011 03:46 PM
Aardvajk
God grief, that video is remarkable. This tech spells the death of the travel industry as we know it.
February 18, 2011 04:07 PM
Matias Goldberg
Amazing!

I just happen to be working on my own water rendering implementation, but it doesn't look nearly as good as yours.
Mine is more "look-good-enough" oriented, mainly due to time constraints. Congrats and thumbs up!
February 19, 2011 12:31 AM
Madhed
Welcome to Rekall, eh Aardvajk? ;) Really, really nice. Wonder what system specs you need though.
February 19, 2011 12:50 AM
HydroxicAcid
That looks incredible! I just want to jump into that video and relax on the beach. [img]http://public.gamedev.net/public/style_emoticons/default/cool.gif[/img]
February 19, 2011 01:11 AM
Gaiiden
It's funny you should mention that Aardvajk, because watching this I totally feel the urge to put up my feet and grab a drink with a little umbrella and watch the waves roll in as the sun sets.
February 19, 2011 01:32 AM
CodingCat
Thank you for this very concise article. Especially the way you handle breaking waves is really nice in that it is both simple and seems to yield quite perfectly plausible results. A few things I was wondering about while reading: Are you re-computing the wave tiles every frame or are you simply sliding multiple layers of precomputed waves of different directions and frequencies alongside each other in their corresponding directions in order to perform wave animation? Especially considering all the skewed variations, it seems to me there would be quite some cost involved re-rendering all these every single frame, yet your implementation seems to run quite smoothly.

Another thing that struck me was that I could not spot any kind of actual scene reflection whatsoever, surprisingly, I don't really seem to miss it either. Finally, it would be interesting to know what level of geometric tessalation it takes to get these nice, quite pronounced wave shapes. I presume you're using both geometric deformation and some kind of normal mapping to render such detailed ocean waves?
February 19, 2011 02:39 PM
cameni
For open sea there is just one wave tile that is repeated over the whole area. It accumulates some 64 waves. That tile is precomputed each frame in shader. Each wave moves in its direction with its computed speed; additionally wave decays over time (with amplitude going to 0), when it is replaced by a newly generated wave.

During the rendering shader looks up the wave height for given position, and it also takes the current distance from shore and uses it to look up into a small texture with surf wave shapes. The texture has 64 samples for wave shape, and 16 wave shapes with skew changing from 0.6 to 1. Resulting water height is obtained by summing the height values from surf waves and open sea waves. The textures also store u,v derivatives so the code can compute the normal at the same time.

You are right, there's no scene reflection yet. It is noticeable mainly when there's a higher terrain in the way, and during the daylight.

Tesselation looks like this:
[img]http://www.outerra.com/shots/water-wire.jpg[/img]
February 19, 2011 06:00 PM
rioki
Really really really nice work. But...

I happen to be an occasional surfer. The water looks quite realistically for a calm day on a large lake. How well do the waves scale up? I am thinking of a swell of around 1-2 m... True, I must admit that rendering shore waves is a real challenge.

One thing I want to note, waves normally don't align themselves along the shore. Waves keep the basic direction and get slightly deflected by the shallows. This is quite important for surfers, because that means that waves start breaking at a specific point and keep breaking for quite a long time. If they did align along the shore and the shore happens to be quite straight they just go flop. Occasionally you see this nature... That are the days when you tend to hand out in a bar instead...
February 21, 2011 08:06 AM
cameni
[quote name='rioki' timestamp='1298275600']<br>Really really really nice work. But... <br>
<br>
I happen to be an occasional surfer. The water looks quite realistically for a calm day on a large lake. How well do the waves scale up? I am thinking of a swell of around 1-2 m... True, I must admit that rendering shore waves is a real challenge. <br>
<br>
One thing I want to note, waves normally don't align themselves along the shore. Waves keep the basic direction and get slightly deflected by the shallows. This is quite important for surfers, because that means that waves start breaking at a specific point and keep breaking for quite a long time. If they did align along the shore and the shore happens to be quite straight they just go flop. Occasionally you see this nature... That are the days when you tend to hand out in a bar instead...<br>[/quote]<br><br>No, it cannot simulate large rolling waves that would be good looking from close ups - this would require additional geometry and specialized shaders. That, and the wave physics isn't making it suitable for a surfing simulator at the moment - it would require a better simulation. But I guess it could be done in this system .. under the right circumstances :)<br>
February 21, 2011 04:10 PM
gimbal_
My jaw is in the floor. Luckily you don't need your mouth to type.

Amazing!!!
February 22, 2011 10:02 AM
owl
Beautiful indeed!
February 23, 2011 11:00 PM
Tsuki no Hikari
It's stuff like this that further inspires me to want to create something like this someday. It also emphasizes just how much the big companies tend to care so little for immersion and rather go for the flash and action.
February 27, 2011 06:32 PM
You must log in to join the conversation.
Don't have a GameDev.net account? Sign up!
Profile
Author
Advertisement
Advertisement