Creating Ocean Surfaces with the HOT Plugin for Maya and Arnold
Houdini Ocean Toolkit for Maya is an implementation of Drew Whitehouses Houdini Ocean Toolkit (HOT) for rendering deep ocean waves using the algorithms of Jerry Tessendorf described in the SIGGRAPH 2004 course notes. Nico Rehberg ported this code to Maya and Mental Ray / Arnold.
To get started download the plugin from Nico Rehbergs website.
Unpack the .rar archive (with 7zip e.g.) and go to hotOcean_Maya > Release > deformer > 2016 > win64 and copy the hotOceanDeformer.mll file
Paste it into Maya’s default plugin directory:
now go to hotOcean_Maya > Release > mtoa > 1.0.0 > win64 and copy the aiHotOcean.dll file
Paste it into Arnold’s shaders directory:
Notice: Every time you update the Arnold plugin you need to copy that aiHotOcean.dll file to the shaders directory.
Restart Maya, open Maya > Windows > Settings/Preferences > Plug-in Manager and activate hotOceanDeformer.mll.
Now let’s test the deformer. Create a Polygon Plane and change the subdivision and size parameters to 100. With the plane selected paste the following code in the MEL at the bottom (complete with semicolon):
deformer -type hotOceanDeformer;
Hit Enter. Now the plane should be slightly distorted. To make the effect more obvious we go to the hotOceanDeformer tab in the Attribute Editor and change Resolution to 7, Size to 100 and Wave Height to 5.
By scrubbing on the timeline the waves should move.
Using the HOT deformer is great when you need to see the shape of your waves instantly in the viewport, for instance when you want to place objects on the water surface. The drawback of that method is it can slow down your computer if you need to create large water surfaces with a high amount of subdivisions.
A smarter solution is using the aiHotOcean displacement shader. Let’s try that.
Select the deformed Polygon Plane and hit the H key to make it invisible. Create a new Polygon Plane and change Width and Height to 100. Subdivisions can remain at 10×10. Assign a new ai Standard material and click on the little Output Connection icon.
You will be directed to the Shading Group node. Click on the Displacement mat. icon in the Create Render Node window, navigate to > Arnold > Texture > Utility and select aiHotOcean.
Go to the Hypershade editor and connect the Out Color port of the aiHotOcean with the Vector Displacement port of the displacementShader node.
Select the aiHotOcean node in the Hypershade editor and change the parameters to match the settings we previously entered in the hotOceanDeformer. Select the Polygon Plane and in the Attribute Editor go to the pPlaneShape tab change under Subdivision > Type > catclark, Iterations > 4, Bounds Padding > 1.000. To prepare it for rendering as transparent surface deactivate also Opaque.
Add some HDR light to your scene as described in Part 3. The rendering in the IPR now should look like the plane with the hotOceanDeformer method. You can compare both methods by alternating their visibility with the H key and the command > Keep Image in Render View.
Change the diffuse weight of the water surface material to zero, raise Specular and Refraction Weight to 100, activate Fresnel at both and change the Refraction IOR to 1.333. To block lighting from below create a new 100×100 Poly Plane, move it far below water level, apply a new aiStandard Material and change the Diffuse Color to a dark turquoise. Add a background image as described in Part 4. Tweak the aiHotOcean shader until it fits your idea. The first 3 parameters are the most important, see the description below. Plese note, that every time you change shader parameters you need to refresh the IPR preview.
In the final rendering I added some fractal noise in the bump channel of the water surface to make it look more interesting. If you want to add ocean spray with particles you can find a tutorial here.
That’s the description of the parameters from the documentation:
- Global Scale – This resizes the whole system, to fit it into different scene scales
- Resolution – This is the resolution of the grid that the ocean will be simulated on. You can think of it in the same way as you would a texture image that you would tile the ocean surface with. The resolution of the image would be 2 to the power of res so e.g. res=10 would make a 1024×1024 image. Be warned, going to res=11 means you are going to use quite a bit of memory since the code uses more arrays of this size to store intermediate computations.
- Size – The grid mentioned above is computed for and applied to the input geometry in tiles of this size.
- Wind Speed – Affects the shape of the waves. High speeds smooth the waves.
- Wave Height – Roughly the height of the biggest waves.
Shortest Wavelength – Waves below this length will be filtered out.
- Choppyness – The amount of chop displacement that is applied to the input points. Makes sharper waves. 0 turns it off.
- Wind Direction – Affects the direction the waves travel in.
- Damp reflections – In a “fully developed” ocean you will have waves traveling in both the forward and backwards directions. This parameter damps out the negative direction waves.
- Wind Alignment – Controls how closely the waves travel in the direction of the wind.
- Ocean Depth – Affects the spectrum of waves generated. Visually in doesn’t seem to have that great an influence.
- Time – The time that the surface will be evaluated at. You will usually feed it with a time expression.
- Seed – Seeds the random number generator.
- Texturespace – The waves can either be generated in world, object or tangent space. In worldspace any translation, rotation or scale values of your mesh are ignored. In object space they do translate, rotate and scale. In tangent space they are generated according to the uvs, so they will also follow deformations.
- Interpolation – smoothes the generated points at the cost of speed.