# Outerra forum

## Outerra Engine => Technology => Topic started by: Aekold on November 22, 2011, 07:44:45 am

Title: Ocean rendering
Post by: Aekold on November 22, 2011, 07:44:45 am
Which technology do you use for the foam rendering? Do you have any ideas how to make breaking waves?
Title: Re: Ocean rendering
Post by: cameni on November 22, 2011, 09:33:50 am
Foam is just a moving texture applied to areas with steep slope, with rising probability as the water gets closer to a shore. Geometry of waves is rather simple at the moment, it's basically a heightfield without overhangs, it only makes an illusion of breaking wave. Full breaking waves would need to be modeled better, or the front part would have to be modeled as an addition to the existing water shape.
Title: Re: Ocean rendering
Post by: Aekold on November 22, 2011, 09:51:36 am
You wrote that you store the wave profile for different skew factors. Do I understand correctly that this is an array of 1D periodic functions?
If yes, how you then convert it to the 2D height function when you need to create a shore wave depending on the distance field value?
Title: Re: Ocean rendering
Post by: cameni on November 22, 2011, 10:11:37 am
Yes, it's an array of 1D functions, but stored as a 2D texture, so that it's interpolated when you perform a lookup to it using the wave position and skew factor. So for the given point you compute the current position within the wave sample, and its skew factor (from distance to shore and depth, and current time). This creates waves moving synchronously towards the shore, with changing front as they near the land. To break up the artificial synchronous rhytm there's another random map generated, that's also changing over time, that basically controls selection from multiple such waves (each with a slightly different period, wave speed etc) coherently for continuous 10-20m regions.
Title: Re: Ocean rendering
Post by: Aekold on November 23, 2011, 07:52:10 am
Thanks!
I try to experiment with the skewed trochoidals - what is the sensible range for parameters b and gamma?
Title: Re: Ocean rendering
Post by: Aekold on November 23, 2011, 08:01:19 am
i. e., which parameters were used to generate the wave profile here:
http://1.bp.blogspot.com/-JgtSygJ9i0k/TV13w2tPXUI/AAAAAAAAAFw/T77xJGYLuC4/s1600/trochoid2.gif (http://1.bp.blogspot.com/-JgtSygJ9i0k/TV13w2tPXUI/AAAAAAAAAFw/T77xJGYLuC4/s1600/trochoid2.gif)
?
Title: Re: Ocean rendering
Post by: cameni on November 23, 2011, 08:21:19 am
I used Microsoft Mathematics (http://www.microsoft.com/education/ww/products/Pages/mathematics-4.0.aspx) to visualize and tune the waves, with this equation:

Code: [Select]
`show2d(plotparam2d(t-0.05sin(2pi(t-floor(t))^0.4),0.25cos(2pi(t-floor(t))^0.4),{t, 0, 10},{x, 0, 10},{y, -1, 1}),{x, 0, 10},{y, -1, 1})`
b should be something small, like the 0.05 there, to avoid overhangs. Gamma 0..1
You can toy with the parameters there, to see how it looks.
Title: Re: Ocean rendering
Post by: Aekold on November 23, 2011, 09:20:01 am
Thanks a lot again!
I am sketching in Wolfram and it looks very similar:
http://www.wolframalpha.com/input/?i=parametric+plot+%28t-0.05sin%282pi+frac%28t%29^0.5%29%2C0.25cos%282pi+frac%28t%29^0.5%29%29+t+from+0+to+1 (http://www.wolframalpha.com/input/?i=parametric+plot+%28t-0.05sin%282pi+frac%28t%29^0.5%29%2C0.25cos%282pi+frac%28t%29^0.5%29%29+t+from+0+to+1)
Title: Re: Ocean rendering
Post by: cameni on November 23, 2011, 09:49:22 am
Yes, I would use Wolfram today :)
Title: Re: Ocean rendering
Post by: Aekold on November 24, 2011, 08:54:53 am
How do you keep the computational time reasonable? Do you calculate only those shore waves inside a frustum? If yes, are they all synchronized so an observer can rotate his head forth and back and see a correctly travelled (while an observer was not seeing it => it was not processed) wave?
Title: Re: Ocean rendering
Post by: Aekold on November 24, 2011, 10:09:00 am
One more question: do you increase a frequency as a wave approaches a shore?
Title: Re: Ocean rendering
Post by: cameni on November 24, 2011, 11:06:46 am
The shore waves are only computed for tiles that actually touch the shore. Open sea waves are always computed, and then superimposed over the beach waves.

The wave computation is stateless - the wave height only depends on the current time, distance to shore and water depth, but not on the previous values of height or the neighboring points. A full simulation would be too heavy.

Increasing the frequency with shortening distance - would be possible, but it may introduce a shear effect. Variables that continuously change can have various ugly effects with this approach, for example the gradient map must be sampled in a discrete manner when used for foam rendering, otherwise the apparent foam movement will have wild directions. Took me a while to figure out, too.
Title: Re: Ocean rendering
Post by: Aekold on November 24, 2011, 11:32:09 am
Interesting to notice, thanks!
Let me clarify one point.
Say you have a large island with a very long shoreline - will you generate all the shore waves on the tiles, touching the shores or only for the visible tiles?
Title: Re: Ocean rendering
Post by: Aekold on November 24, 2011, 11:41:09 am
I also wonder how you resolve an issue when a shore wave meets the shoreline. I've got a problem that it 'disconnects' from the ocean and continues running through the beach. On youtube videos from Outerra I've seen that this does not happens there, so it creates a nice surf effect. How do you achieve this?
Title: Re: Ocean rendering
Post by: cameni on November 24, 2011, 12:55:18 pm
Interesting to notice, thanks!
Let me clarify one point.
Say you have a large island with a very long shoreline - will you generate all the shore waves on the tiles, touching the shores or only for the visible tiles?
Only the visible ones. Or better said, only the visible ones that need the level of detail.

Quote
I also wonder how you resolve an issue when a shore wave meets the shoreline. I've got a problem that it 'disconnects' from the ocean and continues running through the beach. On youtube videos from Outerra I've seen that this does not happens there, so it creates a nice surf effect. How do you achieve this?
Two things - tuning the slope of the trailing part of the wave, so that it's lower than some average shore steepness, and attenuating the wave when it goes inland. The issue still occasionally appears here and there though.
Title: Re: Ocean rendering
Post by: Aekold on November 25, 2011, 01:24:23 am
Thank you for your detailed answers!
How do you calculate foam factor (how much foam you should render) near the shore? Do you use world depth or screen-space depth?
If first, how do you pass to to the GPU and how to you store it, if second, how do you avoid different foam factors at different view angles as it is here:
http://www.youtube.com/watch?feature=player_detailpage&v=UMHgBplll8Q#t=202s (http://www.youtube.com/watch?feature=player_detailpage&v=UMHgBplll8Q#t=202s)
(watch from 3:22)
?
Title: Re: Ocean rendering
Post by: cameni on November 25, 2011, 10:30:08 am
Hmm, I'm simply using the distance map to shore to determine the static foam factor, combining it with dynamic foam strength value stored as the second channel in the wave profile texture.
Title: Re: Ocean rendering
Post by: Aekold on November 28, 2011, 10:06:44 am
How do you define the shape of the wave? Is it deformed by the distance field or is the center of the wave always ahead of the side parts?
Title: Re: Ocean rendering
Post by: cameni on November 28, 2011, 10:39:25 am
I'm not sure what you mean here. The distance determines the shape, as it serves as the second coordinate into the trochoid shape texture.
Title: Re: Ocean rendering
Post by: Aekold on November 28, 2011, 04:13:41 pm
I mean not the profile, but the shape of the wave front (i.e., projection of the wave of the ocean plane).
Title: Re: Ocean rendering
Post by: cameni on November 29, 2011, 03:58:41 am
Um, maybe I didn't explain myself clearly. Let me describe the process again:
• water geometry comes in the form of quad-tree meshes, same as terrain, except it's all on sea level
• vertex shader takes the coordinates of current vertex and looks up the distance to shore in the distance map
• using this distance, current time, current sea depth and some timing constants it fetches the wave height from the trochoid texture, as I described earlier
• the obtained height is subjected to some filtering, attenuation if it's inland etc, and it's used to displace the input sea-plane coordinates in the direction of the normal vector
That's essentially all there is. The waves appear as the result of this algorithm.
Title: Re: Ocean rendering
Post by: Aekold on November 29, 2011, 05:47:14 am
So, the wave is not a separate object, right?
How do you achieve then that the waves appear separately, not in a continuous front?
Title: Re: Ocean rendering
Post by: cameni on November 29, 2011, 06:34:28 am
No, it's not a separate object. I wrote about why they appear separately earlier here:
... for the given point you compute the current position within the wave sample, and its skew factor (from distance to shore and depth, and current time). This creates waves moving synchronously towards the shore, with changing front as they near the land. To break up the artificial synchronous rhythm there's another random map generated, that's also changing over time, that basically controls selection from multiple such waves (each with a slightly different period, wave speed etc) coherently for continuous 10-20m regions.

It's the second map that creates batches of waves out of the uniform waves concentric around the shores (con-shoric waves? :D), that smoothly emerge and then vanish, being randomly replaced by another batch with a different phase and slightly different frequency and wave speed.

I should really write a paper about it :)
Title: Re: Ocean rendering
Post by: Aekold on November 29, 2011, 06:55:16 am
Thanks for your patience!
Quote
I should really write a paper about it
Well, that would be super great! I would volunteer to review it then :)
Title: Re: Ocean rendering
Post by: Aekold on November 29, 2011, 10:59:32 am
It's the second map that creates batches of waves out of the uniform waves concentric around the shores (con-shoric waves? :D), that smoothly emerge and then vanish, being randomly replaced by another batch with a different phase and slightly different frequency and wave speed.
Could you please give some more hints about this batch map, how to create and animate it?
Some more formulas on that would be really valuable :)
Title: Re: Ocean rendering
Post by: cameni on November 30, 2011, 06:20:49 am
The goal is simple, to generate a tileable map that contains values used for wave selection and modulation. I'm generating a few random positions in the map, together with the values for peak width and amplitude. Using the position, width and amplitude, the peaks are rendered into the texture (or, rather, a contribution of each peak is accumulated for each pixel) using the following equation:
dx = x - xp;
dy = y - yp;
h = A*exp(-(dx*dx + dy*dy)/W) (http://www.wolframalpha.com/input/?i=plot+0.2+exp%28-%28x*x%2By*y%29*10%29%2C+x%3D-1..1%2C+y%3D-1..1)
(It's not cut, I don't know how to set the z-range in Wolfram Alpha)

Since it's just a single channel, I'm using positive/negative amplitudes to select from two wave functions, giving appearance of multiple non-uniform waves.
The amplitudes are also animated - when a peak is generated, it's amplitude is initially set to 0, slowly changing to the desired amplitude over time and then back to zero. Once it reaches zero, another set of parameters is generated.
Title: Re: Ocean rendering
Post by: Aekold on November 30, 2011, 07:13:20 am
Huh, so simple :) Thanks!
I was trying to paraemterize the wave along the wavefront - that's a devil)
Title: Re: Ocean rendering
Post by: cameni on November 30, 2011, 07:59:31 am
Tried that one too, no way :)
It's impossible to get the second coordinate (along the contour, the first one being the shore distance). Nothing that would be continuous and universal.
Title: Re: Ocean rendering
Post by: Aekold on November 30, 2011, 08:43:10 am
Well, if the islands, generating shore waves, are well away enough, you could.
You can put the circle center in the middle and stretch it from inside until it hits the shoreline. Then you can use original angular coord from the circle to parameterize the shoreline. You can then normalize it by calculating the shoreline perimeter and adjusting coords according to real distance (so they are not overstretched or overshrinked due to relief). Then you can continue dilating it radially to spread the same coords to the shore waters.
Should work even if the island is not convex.
Title: Re: Ocean rendering
Post by: Aekold on December 01, 2011, 04:08:21 am
Do you modify the wave's frequency dependant on depth/distance in the point? Or do you modify only the amplitude? If yes, how?
I've got an issue with a wave, disconnecting from ocean.
Title: Re: Ocean rendering
Post by: cameni on December 01, 2011, 04:22:09 am
Can you show it?
The frequency is constant, distance affects only the phase. Amplitude is modulated on both ends - on large distances from shore it starts slowly from zero, and then once on the land it falls back to zero more quickly. The constants are specific to the sizes of our tiles.
Title: Re: Ocean rendering
Post by: Aekold on December 01, 2011, 07:32:38 am
(http://img683.imageshack.us/img683/2432/disconnectingwave.png)
I've color-coded wave height with red, so you can see it distinctly. The 'disconnected' wave is circled with blue.
The effect appears mostly when the shore is very gentle.
Title: Re: Ocean rendering
Post by: cameni on December 01, 2011, 08:36:50 am
I see, yes it's a problem with gentle slopes. Did you try to attenuate it with the distance inland? I've got this voodoo for it there:

amp *= saturate((0.6-w)*10);

With w being the signed distance to shore, >0 on land, <0 on water.
Title: Re: Ocean rendering
Post by: Aekold on December 01, 2011, 09:15:04 am
Yes, I tried different attenuations.
I am currently using exponent, but, perhaps, will switch to your magic instead and experiment with some parameters :)
Title: Re: Ocean rendering
Post by: cameni on December 01, 2011, 09:25:39 am
It still doesn't solve all the cases. The problem is the slope, but I'm thinking that something could be done about it. Once inland, the skew could be computed so that the trailing part of the wave matches the slope of the shore, or interpolates towards it. Together with the attenuation it would mean that as long as the peak is above terrain, the trailing part is too.
Title: Re: Ocean rendering
Post by: Aekold on December 01, 2011, 01:51:36 pm
Might work! Please, let me know if you find something
Title: Re: Ocean rendering
Post by: Aekold on December 03, 2011, 04:51:03 am
I've got one more question about wave shape. Do you render waves which cannot be described as a height function y = f(x)? E.g., when gamma is 0.5, for x = 0 there two y values of the curve. How do you handle this? Or you just use gamma values when for any x there is only single y = f(x) value?
Title: Re: Ocean rendering
Post by: cameni on December 03, 2011, 05:17:57 am
I limited the function parameters to ones where the function is not multivalued, as it would cause graphical glitches anyway. Else, I'm generating the profiles at startup using Newton-Rhapson method, that will end up in one of the solutions, depending on the initial conditions, and thus it would not be well-defined.
Title: Re: Ocean rendering
Post by: xieweibo on October 30, 2014, 08:09:34 am
Hi,
The shore wave and foam is great, Would you give some details(maybe some shader code) for the shore foam which looks really realistic.：）
I had tried the shore wave and get the basic shore wave workable, but they are continue all around the shore, I notice you use another texture to avoid this, would give some information of this(What the texture should be, how does change with time?)
Thank you very much.
Title: Re: Ocean rendering
Post by: cameni on October 30, 2014, 11:31:26 am
First, there are two separate shore wave frequencies, and the one to use at given place is selected using a helper texture that contains islands of values from -1 to 1, but usually its 0.

This texture that breaks the continuous shore waves is generated procedurally, and is made of a bunch of randomly generated circular gaussian peaks which are initially generated (position, size, positive or negative amplitude), and then rendered into the texture over their lifetime, growing from 0 to peak amplitude and back. After the peak falls back to zero, new peak parameters are generated and the peak starts appearing somewhere else. These peaks correspond to the shore waves appearing and disappearing

Pixels in the texture are rendered using the following equation:

Code: [Select]
`float v=0;for each active peak:    //this is to make it seamless    vec2 p = abs(texcoords - peak_coords);    p = min(p, abs(p-1));    float d = dot(p, p);    v += amp * exp2(-d*inv_peak_size);`
Title: Re: Ocean rendering
Post by: xieweibo on October 30, 2014, 11:00:12 pm
Thanks for your kindly reply.
Now, I basically understood how to break continue shore wave, still some thing need to confirm.
The procedure is tiled for the whole terrain? How to solve peaks overlap?(Use alpha blend?)

For the foam in attachment(I don't know how to insert an image, sorry) would give some detail, it's really beautiful.(Some shader code and related texture).
Thanks a lot.
Title: Re: Ocean rendering
Post by: cameni on November 01, 2014, 10:54:25 am
Yes it's tiled for the whole terrain, it does not have any information that's terrain specific - it's just a mask that breaks the surf waves.

Our foam textures can be found in textures/terrain folder, it either applies to wave peaks or to water close to the shore, nothing special shader-wise.
Title: Re: Ocean rendering
Post by: xieweibo on November 03, 2014, 08:42:48 pm
Thanks a lot. :)
I'll have a try. I still have 2 quaestions:
1.Where was the gradient of distance map used?
2.For the shore wave it's normal is different from ambient wave, is some special operations to solve this?
Title: Re: Ocean rendering
Post by: cameni on November 04, 2014, 12:47:17 am
1.Where was the gradient of distance map used?
In the lookup into the foam textures, which are animated in the direction of the shore. The coordinates are computed as C*time*gradient + static tile coordinates.

Quote
2.For the shore wave it's normal is different from ambient wave, is some special operations to solve this?
Not sure what you mean here; the surf waves are skewing towards the shore as described on the blog (http://outerra.blogspot.sk/2011/02/ocean-rendering.html), which is done using the distance-to-shore map.
Title: Re: Ocean rendering
Post by: xieweibo on November 04, 2014, 02:08:05 am
Quote
2.For the shore wave it's normal is different from ambient wave, is some special operations to solve this?
Not sure what you mean here; the surf waves are skewing towards the shore as described on the blog, which is done using the distance-to-shore map.

I mean there is an ambient wave, for the shore it's another wave, each wave have different normal, how do you solve this?
Title: Re: Ocean rendering
Post by: cameni on November 04, 2014, 05:38:05 am
2.For the shore wave its normal is different from ambient wave, is some special operations to solve this?
Aha, that "it's normal" confused me :)

Normals are computed dynamically from partial derivatives of both types of waves, which are computed algorithmically.