Houdini 20.5 Solaris and Karma

How LOPs work

How Solaris LOP (lighting operator) nodes work to generate/modify USD.

On this page

You may want to read USD basics first to become familiar with USD terminology.

Procedural USD

Editing USD involves applying changes to a tree of prims and properties on the prims. A program that let you select prims on the tree and edit the parameters directly might be more straightforward to understand than Houdini, which generates/edits the tree as the side-effect of cooking a procedural network of nodes. However, the procedural paradigm has several compelling advantages for working with USD:

  • Generate USD dynamically.

    USD is inherently not dynamic. Solaris can act as a dynamic layer above the USD, generating different USD output based on expressions, global variables, scripts, database queries, or whatever other inputs you need.

  • Generate USD procedurally.

    For example, if you want 100 instances of a light, you don’t need to write 100 references, just create them using a for-each loop.

  • Work at a higher level.

    For example, USD currently does not have constraints. Solaris provides constrains such as Look At that are “live” in the LOP network, but baked out when you output USD.

  • Bundle useful bits of a LOP network into a reusable digital asset.

Ways of working with USD

You can use Solaris to work with USD in different ways, depending on how USD-centric your studio is, and where you are in the pipeline. For example, the following workflows use HIP files and USD files in different ways:

  • Start with a blank HIP file, build up a LOP network, write out USD (for example, baked out simulated geometry) at the end for other people to consume.

  • Start with a USD file, ingest it into a LOP network, modify it, add to it, and write out modified USD at the end.

  • Create HIP files to generate USD assets in LOP networks. Then have “higher-level” HIP files that use LOPs to load in those assets and combine them into a larger scene/shot.

One important thing to remember with USD is that “an asset” doesn’t just mean a piece of geometry, or a texture. A USD asset might represent several layers of creation and revision, and have relationships to other files (such as textures or imported geometry).

Layers

Understanding how LOPs handle USD layers is helpful in understanding what the nodes do.

  • The output of every LOP node is fully-composed USD stage.

    • A node with an input and output will take the input stage, make a new stage with modified copies of the prims it needs to change, and output the modified stage.

    • The stage’s root layer is always empty except for a stack of sub-layers.

    • These sublayers may be created by a LOP node, in which case they will be anonymous layers that exist only in memory (for example, the SOP Import LOP imports geometry from a SOP network), or they may be layers on disk (the Sublayer LOP imports USD files from disk).

    • LOP nodes never allow for layers loaded from disk to be modified directly. Edits go into an override layer above the loaded layer.

  • LOPs that apply edits (usually) go into the strongest in-memory layer in the sublayer stack.

    • Because the root layer is empty, this means that LOPs nodes are always editing the layer with the strongest opinions on the stage. This ensures that edits applied by each LOP node are always visible, as they cannot be overridden by stronger opinions elsewhere in the stage.

    • If the strongest sublayer is a file on disk, the next LOP node that makes an edit will automatically create an anonymous in-memory layer to hold the edit. The network never modifies layers from disk, it only overrides them on a higher layer.

    • Solaris does not use the USD concept of an Edit Target. However, you can get a similar result using specialized nodes such as Load Layer, Layer Replace, and Edit Target Layer.

  • The current strongest in-memory anonymous layer is often called the active layer in the UI and documentation.

  • Some LOP nodes modify the sublayer stack itself.

    • The Merge LOP merges layers (from disk and in-memory) from different node chains into a single layer stack.

    • The Sublayer LOP loads a sublayer from a USD file.

    • Some LOP nodes (such as the Layer Break LOP the Configure Layer LOP) can create a new anonymous layer on top of the stack. These can be useful when you need full control over which edits are in different layers (and are saved in different USD files).

    • LOP nodes have a Debug flag. When this flag is on, the changes made by the node are always put in their own separate layer, to make them easy to isolate and inspect.

    • The Stage Manager LOP can flatten the layer stack into a single new anonymous active layer, then make edits to that one layer.

    • The Sublayer LOP and Reference can rearrange layers into a form that is compositionally equivalent but creates a cleaner structure of USD files on disk.

Saving layers to disk

In a “pure USD” workflow, where you were writing USD files directly, you would manually segregate data into files based on how you wanted the layers to compose.

In the Solaris procedural workflow, where you can generate many layers in-memory as a result of cooking the network, you can specify a file path for any layer using the Configure Layer LOP. If a layer has a file path, the layer will be written to a separate USD file when you output USD.

Layers that you import (referenced or sublayered ) from disk automatically have the file path set to the file they were imported from.

Layer breaks

Layer breaks are very important to understand. They give you control over what is written to layer file on disk.

The Layer Break LOP does two things:

  • It starts a new active layer which will be modified by following LOP nodes.

  • It marks all existing sublayers as having been authored prior to a layer break.

This has no effect on the composition of the stage. In the scene viewer, you will still see the effects of the sublayers created before the break. However, the break changes the way some LOP nodes work with the layers, and how the USD render node writes them out as USD.

Essentially, when the USD render node writes layers out to layer files on disk, everything before a layer break is thrown away and not written to disk.

Why is this useful?

Imagine you are working in a lighting department. You receive a file from the set dressing department. It contains a landscape, with a scratch light called /Lights/scratch_sun1 created by the set designers. You need to author a layer that removes the scratch light and adds production-quality lighting.

  1. Use a Sublayer LOP to load in landscape.usd.

  2. Append a Layer Break LOP.

    This indicates that nothing above this node should be included when the new layer is written to disk.

  3. Select the scratch light (/Lights/scratch_sun1) and use a Prune LOP to deactivate it.

    Note that because the Layer Break doesn’t affect the composition of in-memory layers, the light is still available to select, even though it comes from above a Layer Break.

  4. Add new production quality lights.

  5. Add a USD render node to write out the network as a layer file called lighting.usd.

    As explained above, the USD render node won’t write anything above the layer break. The file won’t include any data from landscape.usd in lighting.usd.

    However, lighting.usd layer does contain an override saying to deactivate /Lights/scratch_sun1 (the Prune was after the Layer Break, and the attributes it authored aren’t affected).

    Of course, /Lights/scratch_sun1 doesn’t exist in lighting.usd. But when we layer lighting.usd over landscape.usd later, the prim path will match up and the lighting layer will deactivate the scratch light.

So, in a Solaris network, you can load data to provide context for edits, and prevent the “context data” from being written to disk by putting it before a Layer Break node in the network.

Payloads

By default Houdini loads all payloads (and so they behave exactly like references). But the Configure Stage LOP and the load masks controls in the Scene Graph Tree pane allow you to disable default loading of payloads, and then choose which specific payloads you want to load.

  • By default, the USD stage will always load all payloads. This means all payload contents are always visible in the scene graph tree, and that payload contents can be found by LOP node primitive patterns, and potentially edited by the LOP nodes.

  • In the Scene Graph Tree pane, you can choose which payloads appear in the viewer, allowing you to selectively avoid loading and drawing geometry data in the payload. The LOP network can still modify the USD primitives in the payload, this only affects what appears in the view.

Unloading payloads

For extremely large scenes were even just loading and composing the USD tree data in payloads might be slow, you can disable loading and composing of payload data:

  • The Configure Stage LOP lets you specify that Houdini should not load/cook certain payloads.

  • A Sublayer LOP with no inputs can specify that Houdini should not load/cook payloads in the layer.

Preventing payloads from cooking at all can make extremely complex scenes faster to work with, however you need to keep in mind the following consequences when payloads are not cooked:

  • The payload contents don’t show up in the scene graph tree.

  • The payload contents won’t match against primitive patterns in LOP nodes.

  • The payload contents won’t be affected by LOP nodes.

If a payload is not loaded/cooked, the payload primitive appears in the scene graph tree pane with a red dot. This indicates it cannot be shown in the viewer. (While technically the viewer could stream the geometry from the payload off disk, doing so could potentially be misleading, if the LOP network would have modified the contents of the payload if it had cooked.)

Important nodes

Creation

Layout

  • The Transform LOP and Edit LOP are analogous to the Transform SOP and Edit SOP: Transform is a procedural node that applies a single transform to selected nodes. Edit is an interactive tool that lets you select and move/rotate/scale different prims as you work, including using collision physics to place objects naturally.

Working with SOPs

  • The SOP Import LOP imports geometry from SOPs into USD geometry prims.

  • The SOP Create LOP lets you create USD geometry “from scratch” converted from a SOP network inside the node.

  • The SOP Modify LOP lets you edit USD geometry by converting it to SOPs, running it through the SOP network inside the node, and then converting the output back to USD.

  • The LOP Import SOP imports USD geometry back into LOPs.

See importing SOP geometry into USD for more information.

Layers and references

  • Merge merges the layers (on-disk and/or in-memory) from different node chains into a single layer stack in the output.

  • The Sublayer LOP imports the layer(s) from a file into the layer stack.

  • The Reference LOP imports a root prim and its descendants from a file and attaches it onto the scene graph tree at a certain branch.

  • The Stage Manager LOP lets you reference in many files into many places in the scene graph tree at once quickly, using a custom user interface.

  • The Layer Break LOP (see layer breaks above).

See the difference between sublayering and referencing for more information.

Output

  • The Configure Layer node lets you set metadata values on layers. You can use it to give an in-memory layer a Save Path, so it will be saved to a USD file when you render out USD.

  • The USD render node writes the stage created by a LOP network out to .usd files. You can use this node in a render network or a LOP network.

    See USD output for more information.

  • The Karma render node is a “one stop shop” for rendering images from USD. It incorporates parameters for render settings and render products for convenience (you can also set up the corresponding USD prims separately using Render Settings and Render Product nodes).

Low-level power

  • The Edit Properties LOP lets you modify attribute values using Schema APIs. You can also package it up as an asset. This lets you make an asset with a higher-level user interface to modify your own custom schema attributes.

  • The Attribute Wrangle LOP lets you modify attributes using a VEX snippet.

  • The Graft Stages LOP lets you “detach” a branch from the scene graph tree and “re-attach” it to a different parent. This is something that is normally very cumbersome to do with pure USD.

  • The Python Script LOP lets you use the USD Python API to modify an editable stage object directly.

Context options

Context options are new in Houdini 18.0. There is a set of global options you can edit using Edit ▸ Context Options. In LOP networks you can also create blocks in which new options or new option values exist only within the block. You can insert context option values in expressions using @optionname.

For example, you could create a shot_name global context option, and set all render nodes to generate filenames using @shot_name as a base, so changing one global option changes all render outputs.

See context options for more information.

Animation

  • LOP nodes always cook only a single frame at a time (unless you use a Cache LOP).

    This means that even if you have animated LOP nodes, the anonymous layers authored by the LOP nodes will only have a single time sample of data. As you move from frame to frame on the playbar, the LOP nodes recook and the layers still have only a single time sample, but it is always a time sample for the current frame number.

  • When you write out the USD using the USD render node, it can cook all frames and write full time samples in the USD output.

  • See how the USD render node writes out animation

  • When you import USD geometry into SOPs, the Time at which the prims are converted is the scene’s start frame by default. If you need to import animated USD geometry, you can set Time to $FF. However, this is often slow and inefficient. You can get faster results by animating the usdFrame intrinsic on the imported USD Packed Prims in your scene, using a Wrangle.

Solaris and Karma

USD

Geometry

  • SOP Geometry I/O

    Details of how Houdini converts SOP geometry to USD, and how you can control the process.

  • Component Builder

    The Component Builder tool puts down a network snippet for creating a USD model from SOPs, with support for materials, variants, payloads, and layering.

Layout

  • Stage Manager

    How to work with the Solaris stage effectively.

  • Edit node

    Interactively transforms prims in the viewer. Can use physics collisions to position props realistically.

  • Layout node

    Provides tools for populating a scene with instanced USD assets. You can place individual components, paint/scatter components in different ways using customizable brushes, and edit existing instances.

  • Custom Layout Brushes

    How to create layout brush digital assets you can use to customize the behavior of the Layout LOP.

Look Development

  • MaterialX

    Houdini has VOP node equivalents of the MaterialX shader nodes. You can build a shader network using these nodes, or import an existing MaterialX-based shader, and use them with Karma (Houdini’s USD renderer).

  • UDIM paths

    You can encode different tiles of a texture space into different texture files, each with its own resolution. You can then specify a texture filename such as kaiju.exr, and Houdini will replace the token with the specific tile address at load time.

  • Shader translation framework

    Describes the Solaris shading framework, including shader node translation to USD primitives.

Karma User Guide

Karma basics and workflows