Houdini Lighting Shading

From cgwiki

There's probably other quick mantra light/shade/render overviews, but I couldn't find any, at least not in the impatient 5 mins or less category that I require. This is my usual kick-the-tyres process I do for any new renderer, thought other curious lighter/shader folk would find it interesting.

Build a simple test scene

Summary: Teapot on floor, with sun, sky, camera.

These quick tuts all assume you're using the 'Build' desktop ( Windows -> Desktop -> Build ), youre famliar with the tab menu and basic houdini navigation.

Lighting setup geo sm.gif

  1. Create a grid
  2. Create a platonic solid, dive inside, set its mode to teapot, radius 3
  3. Dive up, translate it up about 1.39 so it sits on the ground
  4. Create a distant light from the shelf, rotate and translate so it looks nice, tint it yellow
    1. (hint: click the mini colour wheel, then tap where it says RGB, then HSV, until it reads TMI. This is a much better slider for light colour, the first slider controls colour temperature in warm/cool)
  5. Create an environment lights from the shelf, tint it blue
  6. Frame the camera nicely, ctrl-click the camera shelf button which will duplicate a camera for you with those settings

Setup a render node, render

Summary: Create a ROP ( Render OPerator, ie, a render globals node) in PBR mode, which is the preferred renderer these days in most cases.

Lighting setup rop sm.gif

  1. Create a rop network. While you can create rops in the high level '/out' network, I find it easier to keep track of everything in subnets, the jumping around becomes more localised.
  2. Dive inside, create a mantra node. The default settings will point to the camera you just created (/obj/cam1).
  3. Under the 'rendering' tab , set the rendering engine to 'physically based rendering', (called PBR for short by the cool kids)
  4. In the main view, switch to the render view tab
  5. Hit render
  6. Gasp in awe at your sunlit teapot

Material creation

Summary: Create a material from the palette, assign.

Get back to the top of the /obj network if you're not already,

Lighting setup shop sm.gif

  1. Create a SHOP network
  2. Find the 'Material Palette' tab on the lower-right tab
  3. On the right side of the material palette, click the upside-down arrow next to the /shop/ title to collapse it. You should now see that closed.
  4. Click the triangle next to /obj/shopnet1 to open it (this is the shopnet you just made)
  5. On the left, find the mantra surface node under general (6 from the top)
  6. Drag it under the /obj/shopnet1 title. After a short delay, you'll see a shader square named 'mantrasurface'
  7. Go back to the network tab, dive into the shop network, there's the material you just made.
  8. Drag the mantrasurface node directly onto the teapot (can do this in either the opengl view or the render view). This will assign the material.

Another way to assign materials is directly from the object node:

  1. Go back to the /obj network, find the grid node, go to its 'material' tab.
  2. Click the mini node icon, a selector will appear.
  3. Select /obj/shopnet1/mantrasurface'. Enable 'export relative path', hit accept.

If you've left the render view running, you should see the updated material on the objects.

Things to note

The material palette is similar to the maya visor, ie, a place to get and store presets. Like the Visor, its clunky and no-one really uses it. For some strange reason, SideFx decided this is the place to store the mantrasurface node, rather than the expected tab-complete menu in SHOPs, which itself is unusually empty. Fixed in a future version perhaps? (note to self; find a way to add nodes to the tab menu...)

I find using relative paths ( ../shopnet/mymaterial ) easier to read than explicit paths ( /obj/shopnet1/mymaterial ). Also means if you have to copy and paste setups, its less likely to clash with existing nodes in other shots.

The mantrasurface node is the latest attempt by SideFx at an all purpose, mia_material/vray/arnold style all-in-one physically correct shader. It does diffuse, 2 reflect (for base and clearcoat), refract, translucence, emission, opacity, with support for maps on most parameters. The one in H14 has had a bit of a tidy up, the tabs are cleaner, shader parameters better named than previous versions. Prior to the mantrasurface node was the surfacemode node (which you can still find in the palette underthe mantrasurface)

A great feature of the mantrasurface node is you can dive inside and see how it works. A horrible feature is that its pretty messy under there and a bit overwhelming at first! Don't try and understand it all in one hit, its better if you have a specific interest to just dive into that section and poke around, most of it is clearly labelled.

Other Houdini users have made their own versions of an all-in-one physically correct shader. The layered pbr shader on the orbolt store is very nice. A key difference is that its written in vex rather than vop nodes, so isn't designed to be pulled apart. There's also been attempts to recreate the disney bsdf shader, also worth a look. (provide links here)

Material attribute overrides

Summary: Take a material attribute name (say baseColor), create an attribute with the same name at an object or point level, give it a new value, and it will override the material default at that object/point. Very powerful!

Mat attr override.gif

Override at object level

  1. Edit the base colour of the material, render. Both the teapot and floor go green.
  2. Hover over the baseColor label, note that its name is 'baseColorr baseColorg baseColorb'. ie, its a vector of name 'baseColor'.
  3. Select the teapot, go to the material tab
  4. Click the dropdown at the far right of the material name, choose 'select and create local material parameters'
  5. In the popup, choose 'baseColor', Accept
  6. Make this colour red
  7. The render view now shows a red teapot and green floor, even though both are using the same material

From that same dropdown you can choose to replicate the complete material interface on the object, or reset it to defaults, or remove the local overrides. Next we'll override at the point level.

Override at point level

  1. Dive into the grid object, append a point vop, make it the renderable/displayed node
  2. Dive into the point vop
  3. Create a bind export node, set type to 'color', name 'baseColor'
  4. Connect P directly to the bind export node
  5. The 'baseColor' material attribute for the grid has been overridden by the point colour.

The minor complication of point level overrides is knowing the name of the attribute you want (I find the tooltip hover the laziest way), and setting that attribute (my preference is with a point vop, that way I can drive it with vop textures or other tricks).

Assign materials to faces

Summary: The material sop node lets you do per-face assignments.

Per face material.jpg

Example scene: File:per_face_material_assign.hip

Doing per-face assignments in maya is risky, changing them with render layers is disasterous. Doing the same in houdini is perfectly fine. Append a material sop, tell it which material you want, done. You can also assign to face groups if you have them defined.

  1. On left hand side of viewport, make sure the mode is primitives (or hotkey '4' in the viewprot)
  2. On left hand side of viewport, click the arrow to get into selection mode (hotkey 's' in the viewport)
  3. Drag a rectangle to select some faces
  4. Tab IN THE VIEWPORT (important!), choose 'group', it will make a group with the faces you chose
  5. Do the same with another selection of faces
  6. Append a material node, choose a material, and choose a group from the group dropdown. The material will be limited to just that group.

Point Colour (Cd) and Alpha

Summary: Colour attribute is 'Cd', alpha is 'Alpha' (note the capital-a).

The mantrasurface node is setup to read point colours and alpha if they exist (they'll be multiplied against the shader colour). The only trick to remember is to use the right attribute names. Colour is easy enough, as within a vop network its listed on the output node: Cd. Alpha isn't listed though, everyone goes through the same false start of trying the seemingly obvious (Af), then something else (af?), other things (opacity?) until finally remembering the right format: name 'Alpha', of type float.

AOVs or Extra Image Planes

Houdini calls them Extra Image Planes, everyone else calls them AOVs (a renderman acronym for Arbitrary Output Variables). A little more work than in other packages, but the flipside is a lot more freedom to do whatever you want (like most of Houdini really).

Defining AOVs in a shader

In a shader, anything which you connect to a 'bind export' vop becomes available to use as an AOV.

  1. Dive into the shopnet, then into the mantrasurface shader
  2. Create a 'bind export' node, name 'myaov', type 'vector'
  3. Connect N to its input.

You now have 'myaov' ready to be used as an AOV.

Add AOVs to Rop

  1. Dive into the ropnet, select the mantra node
  2. Choose 'Image' Tab, then 'Extra Image Planes' sub-tab. There's some pre-defined AOVs, but we need our new custom one.
  3. Click the + button next to the 'Extra Image Planes' Field, a new sub-collection of parameters will appear
  4. Type 'myaov' into the vex variable field
  5. Make sure the vex type is 'vector type'
  6. Render. Pop out the view bar at the top of the render view (under the render button), and where it says 'C', use the dropdown to choose 'myaov'.
  7. There's the AOV you defined earlier.

Mantra, like most modern renderers, doesn't incur a big speed hit when adding AOVs, more a memory and disk space hit. Its common to add several standard AOVs automatically to most materials and rops, as they're so useful in compositing. Usual suspects are P-cameraspace, P-worldspace, N-world, Diffuse, Reflect, Indirect.

Renderstate vop

Renderstate wiki.jpg

Download scene: File:renderstate.hipnc

When people first start houdini, they tend to treat it like other apps, and make a separate high level object container for each 'thing'. Eventually you realise its easier and more controllable to keep everything within a single object network, and use point/prim attributes to do things like drive colour variation and whatnot.

But what if you do need to keep things seperate, like these cubes, but you want them to all have the same shader, yet be able to give each cube random values? One way is to do parameter overrides as listed above, but another way is with the renderstate vop.

This gives your shader access to render time attributes about your geometry. Here I've used a simple one, object_id, which I've then feed to a random vop, which in turn drives colour variation. There's loads of attributes you can use, very handy.

Note that op_id is volatile, and changes any time you add or remove objects, or even reload the scene. A better way is to generate random numbers from the object names rather than the object_id, which is less likely to change (or if it does change, at least you'll be aware of it). An example of setting that up is here:

Download scene: File:renderstate_by_name.hipnc

(And a note to myself, if you need primnum, use a Get Primitive Id Vop. Thanks to Thomas Slancik, of course)


Following need to be added to this tutorial...

  • gif for Cd and Alpha
  • gif for aov setup
  • per light aovs
  • setting up lightgroup aovs
  • parameter ramps and fit range
  • bind vs bind export
  • viewport preview and GLSL
  • viewport preview modes (standard, high quality, shadows, ambocc, headlight, flat)
  • whats missing (layered shaders, link to shader td's amazing showreel)