Houdini - Stylesheets

Some notes on how to create a simple object level style sheet.

Object level style sheet

We have a geo node called “spheres” which consists of a number of packed primitives. We also have 2 material called yellow & blue. Lets add a style sheet to this object node that lets us assign different materials based on viewport selection.

Style sheet Inspector (Data tree)

Open the inspector for the material style sheets.

  • New Pane Tab Type > Inspectors > Data Tree
  • Choose a Viewer > Material Style Sheets

Add Style Sheet Parameter

  • In the left column of the Data Tree expand the Geo context
  • RMB click “spheres” and select Add Style Sheet Parameter
    • When we do this a tab on the object node parameter pane gets addd. Here we will see the style sheet in JSON form.

Add Style

We have two materials that we will add to the packed geo. We will first add the blue material to all the spheres.

  • RMB click the Style Sheet Parameter and select Add Style
  • RMB click the added Style and rename it to blue.
  • RMB click the added Style and Add Target
    • Since we wish to target the packed primitives the default value of primitives is fine.
  • RMB click the added Style and Add Override
  • Change the Type of the override to Set Material
  • In the Override Value column we can select the blue material.

Now lets add the yellow material. We will now target some of the spheres with viewport selection.

  • RMB click the Style Sheet Parameter and select Add Style
  • RMB click the added Style and rename it to yellow.
  • RMB click the added Style and Add Target
    • The default value of primitives fine.
  • RMB click the target and choose Set Target From Viewport Selection
    • select a few of the spheres and hit enter.
    • This will add a Condition to the target and set the type to Primitive Group and set the value to the selected spheres.
  • RMB click the added Style and Add Override
  • Change the Type of the override to Set Material
  • In the Override Value column we can select the yellow material.

Scene level style sheet

A scene level style sheet has precedence of object level style sheets. Lets create one.

  • In the material style sheet inspector click the New Style Sheet button at the top toolbar. Give it the name looks and click New Style Sheet button.
  • RMB click the created style sheet and Add Style
  • RMB click the created style and Add Override
  • Add some overrides

Shared override sets

Shared override sets lets you specify the look and use it in multiple places. Lets create one.

Add set

  • In the material style sheet inspector click the New Style Sheet button at the top toolbar. Give it the name looks and click New Style Sheet button.
  • RMB click the Shared Override Sets and choose Add Shared Override Set and call it something nice. (we will call it red)
  • RMB click the added set and choose Add Override
  • Add some overrides

Use the set

  • In the left column RMB click the geo that we want to style and add Add Style Sheet Parameter
  • RMB click the Imported Styles and choose Add Style Sheet Reference
  • The default Type value of Embedded Style Sheet is fine
  • In the Value column choose the override set that we created (that we called looks). Now we can use the set in our styles.
  • RMB click the Style Sheet Parameter and Add Style
  • RMB click the new style and Add Shared Override Set
  • In the value column select the shared overide set that we created earlier (the one called red)

Debugging Style Sheets

Object appearance pane

In the Data Tree inspector we can switch to Object Appearance. Here The styles of each object will be listed and we can quickly jump to inspect the styles.

Vieport inspection

We can also use the Inspect Tool in the viewport to view material assignments. RMB click the inspect tool and choose Inspect Primitives and enable Show Material Assignment and finally switch to the select tool to enable the state. Hover over the geo in the viewport to inspect. Note that it can only display the styles applied to the packed primitives not to the individual polygons that makes up the packed primitive.

Unpacking

If we want to see that kind of detail we can use an unpack sop and enable the Apply Style Sheets. To apply a scene level style sheet (named my_scene_style) we enter the snippet below in the scene level stylesheet text area

{
    "importFiles": ["my_scene_style"]
}

Open up the Geometry Spreadsheet at primitive level in the column material_stylesheet you can find what is applied. (To read it easier copy/paste to sublimeText or something). If we unpack even more (increase the unpack iterations) we can dig in even deeper. One drawback to unpacking is that it can be quite expensive to unpack.

HOM scripting

We can use python to both build and inspect stylesheets (hou.StyleSheet)

Scripted Overrides

We have some packed primitives that are assigned a material called test. We want to set a random basecolor from a number of colors we specify with a ramp.

CVEX Shader Builder

First lets create the CVEX script.

  • In the /mat context create a CVEX Shader Builder node and rename it to color_ramp and jump in.
  • Add a Bind node and set Name to id and set the Type to Integer.
  • Create a Random node.
  • Hook up the output (id) from the bind to the input (pos) of the random node.
  • Add a Ramp Parameter and set the name to Color
  • Hook up the output (rand) from the random node to the input of the ramp
  • Create a Bind Export node and connect the color output from the ramp to the input of the bind export node.
  • On the bind export set the Name to clr and Type to Color

Add Style

Now lets setup the material style sheet.

  • Open the inspector for the material style sheets
  • RMB click the packed object and Add Style Sheet Parameter
  • RMB click the Style Sheet Parameter and select Add Style
  • RMB click the added Style and rename it to color_ramp.
  • RMB click the added Style and Add Target
    • The default of primitives is what we want. If we do not specify a target it will target the object itself so everyting will get the same color. (If we add a sub-target each polygon will get a random color)
  • RMB click the added Style and Add Override Script
  • In the Override Name column navigate to and select the base color parm of the material.
  • Change the Override Type to Script From Node
  • in the Override Value select the CVEX node that we created.
  • RMB click the Override Script and select Add Data Binding
    • We do this to let the CVEX script access the id attr that we want to read with the bind node.

Note that you must change the color ramp parameter on the “outside” CVEX Shader Builder itself, not the ramp node inside to affect the colors. You can also set the ramp color points to constant if you want discrete colors with out interpolation.

Master Class 26:19

Set Texture from point attr

Lets say that we wish to override the base color of a shader based on a string point attr. Here is one way we could do that, not sure if it is the most effective way tough. We have a scene where we have copied some polyspheres to a grid (with pack and instance enabled). Lets append a point wrangle to the copy to points and add a string attr that will use a random image of the default butterfly texture. Note remember to enable Use Texture of the base color, and set the base color to 1.0

int i = int(rand(@ptnum*chi('seed'))*7)+1;
s@tn = sprintf('butterfly%i.pic', i);
  • RMB click the Style Sheet Parameter and select Add Style
  • RMB click the added style and Add Target
    • The default of primitive is what we want.
  • RMB click the added style and Add Override Script
    • Set the Type to Material Parameter
    • Set the Override Name to basecolor_texture
    • Change the Override Type to Attribute Binding
    • Set the Override Value to tn (the point attr we created earlier)

RBD Material Fracture & Stylesheets

We have a sphere that we have fractured using the RMB Material Fracture node. Then we have appended a RBD Configure and an RBD Pack node to wrap everything up in one stream. We use a Copy To Points to instance our packed rbd object to a grid and use an RBD Unpack (remember to enable Enforce Unique Name Attribute per Instance) to get our geo, constraints and proxy geo back. This is fed to dopnet with an rbd sim or the RBD Bullet Solver (sop). I wanted to use style sheets to set materials for the fractured inside geo and I wanted to randomize the color of each fractured sphere.

The inside group.

Since the RBD Material Fracture produces Packed Fragments we can not use the inside group in our style sheet. One easy way to get around this is to add a Primitive attribute called for instance inside to the prims in the inside group in the render geo stream. Then we can use this attr in the style sheet. To do this we create a Condition with the type Primitive Group and the value @inside==1

Random color per piece

To get the random color per piece this is what I did.

  • Add a point attribute to the points that we use for instancing the spheres to i@n_id = @ptnum;
  • In the copy to points Attributes from Target transfer the attr n_id to the primitives.
  • In the RBD Unpack transfer the n_id attribute.
  • Create a override script to change the basecolor parameter with a script from node (create a CVEX Shader Builder the randomizes color based on id attr)
  • Add a data binding to the override script. Let the override name be id (if that what was you used in the CVEX node) and set the Override Value to n_id the attr that we created on the copy to points target points and transfered to our prims.