This shot was created in Houdini 19.5 with native flip and whitewater tools. And the comp was done in Nuke.
I was responsible for all aspects except for the models of trees and rocks, and the shaders of the snow and the river.
I will try to breakdown this shot in detail in this post. If you have any question, feel free to reach out, you can find my contact info in my profile.
*If you don't see the videos below playing, please check the autoplay settings on your browser.
Preparation
To create the river, I used a heightfield generation tool called Gaea. It's mainly used for much larger scale terrain, but I tried to play around the settings turning a canyon to a river.
And then I exported the heightfield and brought it into Houdini. I was using the community version of Gaea, so the export was limited to 1k resolution. With the paid version, I could export higher-res heightfield and even the actual mesh, then I could bring it into zbrush to clean it up a bit and use it in unreal as a nanite mesh if I wanted to. Gaea also has some texture tools, it's just that I wasn't using it for this shot.
So back to Houdini.
I altered the terrain a bit more to prep it for the flip sim.
I used heightfield scatter SOP to populate the riverbed with cobblestones and the ground with snowy trees. Lots of built in tools can be utilized in HF scatter tool to randomize asset selections, rotation and scale.
For the ground snow, I first masked out the heightfield with slope angle and height, and then I scattered a bunch of deformed spheres to cover the whole area; finally remeshed them together and polyreduced it down.
I booleaned (VDB combined) the terrain geometry and to create the flip source (surface and points) and boundary layer (VDB only). By using the booleaned shape as my water source, it saved me quite some time and disk space from large amount of pre-rolls.
And then I transferred some directional velocity to the source points (and noised them up); rasterized them to vel field and use it as boundary layer velocity.
And we are all set for simulation.
FLIP
The main flip simulation was quite straight forward. 2 notable settings I changed would be:
- Enabling boundary layer helped maintain a constant volume of water.
- Changing the static object RBD setting to volume sample and using the VDB converted from HF SOPs gave me more control on the collision.
And then is it was caching and meshing. To eliminate meshing artifacts like holes, I extracted the particles and then deleted the droplets part; and then I set up pscale by vorticity and velocity before converting them to VDB and combining with the original surface from the simulation. It recreated a smoother detail for my water surface.
Whitewater
I created the whitewater source from vorticity range.
As for the actual solve, I experimented with the foam settings in the whitewater solver to nail the final result.
After caching out the particles, I used a wrangle to setup the density based on it's age and depth. The code was copied from shell tool WW. And then the density was used to drive the pscale.
I then after rasterized the WW particles and negated the density; computed the gradient and merge them together. But I ended up didn't use the rasterized volume in the render. I actually rendered the particles directly, just with the volume shader and render geo settings set to ''treat as volume.''
2nd Layer fFip and Whitewater
After the first whitewater done, I brought in the river mesh and the rocks collision. And based on the contacted area, I created another set of emitters.
The initial velocity was based on the river flow and the rocks' normal (plus some noise as always). And this particle source was sent into another flip sim to create some extra splashes.
Combining the result with the splashes and the first flip sim I create yet another whitewater source.
And another whitewater sim later, I got my 2nd layer whitewater.
Iterations
Flip solver and whitewater solver are quite slow on my computer, which is a OMEN laptop with intel 12700H and Nvidia 3070 mobile with 32g of ram and 8g of vram. And the Cache takes up a lot of space. So organization and optimization are quite important in my opinion. Deleting unnecessary attributes and fluid compress before filecache is standard operation.
I used a TOP net to schedule my sims before I went to bed. It was rop fetch node and wait for all node connecting one after another. I just needed to set the cache mode of my rop fetch to "write" to force overwrite, because I didn't have much space left to version up too many times in my filecache.
Rendering in Solaris
I created all the assets in object context, so I used SOP import to bring them into Solaris and then assigned materials to them. The snow material I found on sideFX community forum was shared by Andrea Sbabo.
And for the river body, I imported the polygon surface twice, one of which was rendered as normal mesh, the other was rendered as uniform volume, and the density was linked to the shader. The river shader I used was created by Hang Yang and available on Gumroad.
And the whitewater and splashes particles were also brought in points but rendered as volume with default whitewater shader.
And velocity blur was enabled for all water objects.
To tie things up, I set everything to holdout matte and used a karma fog box with low density and high scattering phase. And I rendered it out with XPU(other thing was all CPU).
Compositing
Compositing for this shot was done in Nuke and it wasn't complicated. I added some grades and glows to the AOVs, plussed them together; put the fog box on top. I also grabbed a free stock snowy footage retimed it and added some motion blur and comped it in as well.
Final Result
Thanks for reading the breakdown blog. If you have any question or suggestion, please let me know. And if you find this helpful or interesting, please consider checking out my other breakdown, you can find them on my profile. Cheers.