Let me first say that I'm often visiting my own blog to read how I did certain things. This is mostly true for some of the older, more technical posts. I decided to blog about recent water rendering development in a way that will be helpful for me in time when my brain niftily sends all the crucial bits to desert. I apologize in advance if some pieces seem incoherent.
首先,我想说的是,我经常访问自己的博客,阅读我是如何完成某些事情的。这主要是针对一些较旧的、技术性更强的帖子。我决定以一种将来当我的大脑巧妙地把所有关键信息都发送到沙漠时对我有帮助的方式,来记录最近水渲染技术的发展。如果有些部分看起来不连贯,请提前谅解。
Now for the 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
Other wave parameters depend on the frequency (or its reciprocal, the wavelength). 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:
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:
The equation for skewed trochoidal wave is:
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.
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 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.
Red: 7m, Green: 30m, Blue: 70m, Scattering coefficient: 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.
Scattering coefficient: 0.000 Scattering coefficient: 0.020
Here's a short video showing it all in motion.