In our latest feature movie I have developed a lot of procedural animated water surfaces. Starting from small puddles to huge ocean surfaces - all this stuff was created using procedural custom noises, including Houdini Ocean Toolkit and 2d ripple solver. For a few close-up shots I used FLIP simulations sewed with animated plates. To enhance spatial details I used texture displacement projected with a simple planar projection.
So next I faced the task of creating large scale water simulation. After making some tests I came to conclusion that I can not avoid using texture displacement.
Take notice of the lack of detail on surface
Using simple planar projection mapping with FLIP suffers severe drawbacks, because texture doesn’t reflect base movement. So I needed something more. Inspired by CGEvent Pixar talk and “Running rivers” paper, where authors mention UV advection method, I’ve decided to develop one.
Methods of creating advected flows are widely discussed. A simple one is to create 2d coordinate system and deform it with velocity field. When dealing with fast movement, such deformation leads to high texture distortion and aliasing artifacts in short period of time. That's why this method is often impoved by creating two sets of coordinate systems and blending between them.
In Houdini the idea is just the same as when creating dual rest fields in smoke simulation. We initialize two sets of UV and advect them with the flow. Actulally in FLIP we get advection for free, creating UV’s as particle attribute. Each UV set reinitializes every Nth frame. Then in shader we blend between two textures, based on each UV layer. As a result I created a small HDA, performing all the routines mentioned above. It was quite simple, because in fact I reproduced part of the smoke solver responsible for creating dual rest fields.
Making these impovements I managed to enhance spatial detailization of liquid flow without icreasing the resolution of FLIP simulation.
As you can see in the demonstration I also vary displacement amplitude to prevent artifacts in thin areas. To calculate thickness I used Thickness SOP from qLib library.
Next demo shows the overall process of creating river flow in Houdini. Because I was limited with the amount of particles (~10 millions per simulation), creating proper UVs to make it possible to use displacement was the main challenge. Aslo I tested a method of rendering surface in Renderman directly from VDB. This approach has some benefits allowing not to generate mesh and save a lot of hard disk space.