I completed my latest project Mountain Fractals over a month ago. I wanted to do something with mountain ranges and I knew Houdini would handle this perfectly. Doing this I wanted to take a fully procedural approach to the geometry. I finished this project just before the FMX.
Everything except compositing is Houdini. The mountain range is completely procedural. The shader is procedural, snow amount is slope and height dependent mixed in with noise, you can determine the snow / rock bias for more control. The rocks under the snow is built into the same shader and is controllable with reflection and displacement amount.
There are three smoke sims on the left, top and right of the shot. The top one is a clustered pyro sim. In the top sim I used the velocity field to advect some particles for the snow effect.
In the background the clouds are VEX Volume procedurally generated.
The geometry is created via a tutorial I followed. I created a 1000×1000 grid with 1250×1250 rows and columns which i displace via a pointsop.
I wanted to do some research on how mountains actually get created in other packages like VUE but I didn’t find the time to do so. Most of these packages have really nice options for aging, height, valley and peak creation. Next to that they have really good shading systems as well and are of course built for building huge environmental scenes.
In Houdini I didn’t go that far because I was really happy with the results I could get from just one pointsop. You can see that I am using a for loop to stack noise. Each loop adds more noise on top of the other. The number of for loops controls how many iterations of noise. There are some controls like translate, rotate, offset and lacunarity that go into the for loop that randomize the noise every time it goes through. This gives the whole mountain range more randomness.
Further down the geo pipeline I give the mountain geo a pmin and pmax attribute to use for the shader. These two attributes are the lowest and highest point in the geometry. I can use these two values for determining the amount of snow on the mountain in the shader.
To create that little bit of extra detail I created another point sop to add that extra detail to the already created geometry. At the end of the geo I have a smooth sop to relax the points. The non-optimized geo ended up being 3.5 gigs but was way too memory inefficient since I’m on 32 gigs of ram. The optimized geo returned at around 738mb.
The geometry in the back is generated the same way. Since these are 1000×1000 grids I could use a add sop to create points where I wanted to copy the grids onto. In my showreel below in the breakdown part you can clearly see that the geometry has been copied onto 4 points. Of course this geo has way less details since it was going to be blurred.
VEX Procedural Volume
In the background I also included some VEX procedural volume to mimic the clouds hanging in the valley. This was surprisingly the fastest part of the whole scene to generate. I created a box that covered the entire valley and attached a sky node to it and tweaked the values a bit. That was it, mantra handled the rest.
Cloud & Smoke FX
As mentioned before you can see three simulations in the scene. One on the left, top and right. The simulations on the left and right where ment to look like slow moving clouds that get caught in the mountains nooks and crannies.
I had quite underestimated how difficult it is to control the pyro solver to do whatever you want. Since I didn’t have much experience with the pyro solver I did many iterations of number tweaking before I got what I wanted. If I where to do this again I would go deeper into the pyro solver and study the microsolvers and create a custom velocity field for ultimate control.
I also learned that if you want to have really slow moving pyro the physics of the simulation also start to change. In the end I am most happy with how the clouds of the right behave, those seem closest to the slow moving clouds you see on the sides of mountains.
The simulation on top is a clustered pyro simulation. I added this effect to simulate the snow blowing off the top. Added with some particles advected by the pyro sim to visualize some snow too instead of just snow mist.
Since my wind was coming from one direction I created a point sop which I could control so I could determine where the wind was coming from and create points on the good side of the mountain to emit my smoke from. From there the wind in the DOP would do the rest. The point sop can be controlled by wind direction and slope. Less slope means more snow since it has more chance to accumulate more of it on a flat surface. Mixed in with a little noise this point sop determines which points are used for emission.
The power of shading
This is where most of the magic happens. Everything you see on the mountain (snow, rocks, reflections, coating) is inside one shader. The shader is divided among seven categories: colors, reflections, snow bias, angle/slope, height, noise and displacement.
There are three colors to be controlled in the shader. The rock primary and secondary color and the color of the snow. Plus the added multi matte color. In the reflections you have control over both rock and snow. Both are controllable by specular and roughness. The snow bias is where you control the general amount of snow, this is the go to place when you feel too much rock is exposed. In the angle part of the shader I use a dot product between the up vector and the normal of the surface to determine angle. The angle controller determines how much snow is resting on the steepest parts of the geometry. The height category determines how much snow at which altitude. The noise controller is there to add some diversity to add to the whole snow/rock bias. Finally displacement is where you can control the amount of displacement in the rocky parts of the mountain but there is also control for the amount of displacement for the snowy part. Since there are rocks underneath it.
The video above is a very early test of the shader. You can see that the snow also rests on the displaced parts on the mountain, the tiny details hold snow. It adds surprisingly much detail. In the end the shader does all the work for this scene, it took me quite a while to build and many iterations to get the look I wanted.
There are still some improvements I wanted to add to the snow shader but since the camera stays at a significant distance I left these details for another time. For example I wanted to add a sparkling effect in the coat reflection of the snow. I already did this in my final product, but it is an extremely simple version. It is actually in the render but barely visible.
Rendering the result was quite intense and I learned a lot in mantra during the process. In the end the longest frame took 1 hour and 18 minutes and the shortest frame was about 20 minutes. I did a lot of geometry optimization to get the render times down, because dicing the geometry for displacement was about 8 minutes per frame. Next to that volumetrics will take a lot of your time too.
I needed the volumetrics to have a fine whispy cloud look, which takes more time to render. The less dense a volume is the longer the render will take, so as my camera came closer and closer to the volumetrics on the top part of the mountain the longer the time per frame was. So for the volumes it really was a quality vs performance issue, in the end I think it was quite good because some of the smoke disappears in compositing because of the backplate.
In the Houdini (15.5) documentation it says to render pyro effects with the micropolygon engine. So the next time I do volumetrics I want to see if it can save me time.
The way I rendered the scene was from front to back. The front part of the mountains is what was rendered first, later I added the defocused mountains in the background. This render was significantly faster then the front ones because I knew they where going to be defocused anyway. So I could reduce polygon count on the geometry, disable displacement and reduce the CVEX procedural volume quality too. Most frames where about 3 minutes.
Since I made some errors here and there the first render didn’t have all the AOVs I needed. The position pass for example was being distorted by the volumes in front of the geometry and I still don’t know how to get a decent position pass out of volumes. (This did however work perfectly for the CVEX volumes).
If I had to render this again I would take a different approach now, but that is what makes a learning process so great. I think that I am now much more capable of rendering the elements that I need in one go. I just have to figure out how to get a correct position pass from a volume.
Breaking it down
If you would like to see how this whole thing breaks down take a look at my showreel that I took to the FMX in April. The breakdown for the mountains start at around 0:40.