Phew! It has been a LOOOOOONG time coming, but I’m finally ready to update on the new Gerstner displacement, as implemented within the breaking wave tool. Most of the time it took between the previous update (the sneak preview) had to do with a completely new addition to the displacement of the lip of the wave, which required some dynamic simulation stuff using a Sop Solver in DOP’s.
I’ve now fully integrated the Gerstner logic into the wave system. The main thing I’ve got more work on is the UI. The Gerstner calcs can get you really nice results but the parameters are very sensitive and have strong relationships with each other. This means that sometimes changing a value by a small amount can have really big impact on the final result. By experience I’m starting to get a feel on what relationships between parameters will lead to most natural results so I can build in those relationships into the UI, which will greatly help in setting up nice looking wave displacements quickly.
The basic UI that I’ve implemented so far is fairly similar to one I described in the post: Gerstner wave based displacement and Quick update on Gerstner wave displacements. The only thing that really changed is that the parameters have been moved into some tabs to organize them a bit better.
In addition to the integration of the displacement UI of the Gerstner logic, I’ve moved the VEX code into separate source files and now compile those into a separate displacement tools for geo displacement and displacement shaders. This way I have a lot of reuse out of the code, which really helps maintaining it.
This new VEX code is now used in two distinct places in the tool (with at least 90% reuse of basic algorithms).
- The displacement shader for the water surface
- A set of geo displacement tools that work on displacing the rough area of the wave lip.
The displacement shader is what I have been showing in the posts mentioned above. The geo displacement shaders for the rough area have been hinted at in the ‘sneek preview’ (Sneak preview).
I won’t go into more detail on the displacement shader part (at least not now).
The geo displacement for the rough area on the wave lip deals with two mostly separate issues. The first issue is generating the lip foam texture procedurally, the second providing local geo displacement within the rough area for both the lip spray particle source as a new displacement I’ve dubbed ‘lip curl’.
Lip foam texture
This was already part of older versions of the system, but were then based on the ‘normal’ noise also used for the displacement shaders. Now it is based on the Gerstner calculations. Within the rough area there is a ‘modified’ version of the parameters that drive the displacement which specifically tunes the look of the texture. This means that the amplitude and wave length can be modified within the rough area. This new approach is much simpler than the approach I had implemented for the ‘normal’ noise based displacement as there’s basically two parameters.
In this new system it is also much simpler to get proper black and white values on the texture as I have complete control over the new ‘noise’ function as opposed to the build in functions in Houdini.
The results also look much more like what I observe in real breaking waves. The ‘sneak preview’ render shows the results of the texture added to the overall foam on the water surface.
As in previous versions of the wave this texture also drives the lip spray particle system. The lip spray particle source is based on scattered points within the rough area of the lip. The distribution of these scattered points is based on the same data as the lip foam texture. This means that the brighter the lip foam texture the more particles will be generated, which results in a very nice integration between the water surface and the particles. It now is very hard to see the boundary between the two separate systems. This integration is further enhance by animating the size of the particles over their life cycle. I had not yet implemented that part in the ‘sneak preview’ render and you can see this particularly well where the rough area is just starting (on the right side of the render).
The animation render below shows the difference quite well.
Rough lip displacement on the particle source
The rough lip area for the water surface itself is displaced by the displacement shader during the render. In order for the lip spray particles to actually originate on this displaced surface the particle source points are displaced by the exact same amount using a new geo displacement SOP.
Rough lip curl displacement
There is one thing that kept bugging me about the look of the wave lip in previous versions: it was too smooth. This worked fine for really smooth water conditions where also in reality you can get incredibly clean breaking waves.
However, whenever the water surface through which the breaking wave travels is a bit rougher you quickly start seeing more and more wild ‘oscillations’ in the lip of the wave as it breaks. Based on looking at many different movies of breaking waves in different circumstances I came to the conclusion that it is actually the interaction with the ‘other’ waves and the breaking waves that cause this. When another wave rolls over the breaking wave you see the influence on the lip of the breaking wave. I’m not sure of the fluid dynamic technicalities of this effect but it kind of makes sense on a more intuitive level.
So I figured I needed something that adds displacement to the lip of the wave based on the general water surface displacement. What I quickly discovered is that just adding the water surface displacement of the wave surface itself leads to really unrealistic results, which is mostly caused because the water in the lip moves up and down where in reality it can basically only go down after it ‘breaks’ from the ‘body’ of the wave with gravity.
This quickly led to the realization that the displacement of the water surface should only influence the lip at the time that the water in the lip ‘breaks’ away from the ‘body’ of the wave.
This however would require a value (position or displacement) to be set on each point only when the point is in the ‘breaking’ area (which in my case happens to be more or less the rough area). This value should stay the same afterwards. This means that some kind of ‘memory’ is needed. The point needs to know when it got its displacement value and if so keep the existing value, for this it needs the value of itself in the previous time step. I knew a way to do this was with the SOP Solver in a dynamics context, based on a discussion on the fxPHD forums (though I didn’t know exactly how yet).
The main problem I was facing that my wave is fully animated. The SOP Solver needs to get the geo each time step or the animation is lost in the output of the solve. This however, immediately kills the ‘memory’ in the solve as the values are overwritten from the geo each time step.
After a quite lot of experimenting and many dead ends, I figured out how to do this yesterday. I basically import the geo on which I want to set the attribute only at the intial simulation time step. I get the ‘trigger’ value (the value that decides when the point ‘breaks’ of the wave) from the animated geo. After the SOP Solve has done its little memory trick I then copy the attribute value back to the animated geo and use it to drive the lip displacement.
This lip displacement I call ‘lip curl’. This leads to much better results. The effect of the ‘lip curl displacement’ is controlled by the wave time (so by the time the lip hits the trough of the wave it is back to its original shape and has thus lost any potential upwards displacement). I would be very easy now to further control this using actual gravity to pull back any upwards displacement.
Anyway, currently I’m actually using a separate Gerstner displacement for the ‘lip curl’ but I’m going to change that to have it use the exact same displacement as the wave surface itself. This means that the lip curl is naturally driven by the roughness of the water surface. So when the surface is really smooth there will be a very smooth lip, but when the surface is really rough this will result into an equally rough lip.
I think this should lead to a big increase in realism while still be very easy to control.
Another nice bonus of the ‘lip curl’ is that also very nicely effects the lip spray and makes it more natural as well as the lip curl displacement also influence the position and velocity of the particle source points which in turn passes this on to the particles.
So, without further ado (well.. a little of the disclaimer kind 😉 ) it is time to show some initial animated results of all this new displacement logic. Please note that the general animation of the wave itself is still rather rough and not that realistic and that I’m still using the sunset/tropical shading and background settings. However, I think it does illustrate the new behavior. Also note that, I’ve used fairly low pixel sampling in this render which results in fairly noisy particles.