On this page |
Previous Motion Blur
Overview ¶
This chapter introduces material concepts in Karma and USD, as well as some tips to get up and running quickly.
Tip
If you only wish to use a material to get started with Karma, check out the Quick Materials and come back to this chapter later when ready for more details.
Building materials for Karma is conceptually straightforward, especially if you are familiar with Mantra or some other renderer in Houdini. You create Materials by wiring up a VOP network inside a Material Library LOP. Houdini converts the VOP nodes into USD Material prims and assigns them to geometry. During rendering, Hydra sends the primitives and materials to Karma.
When you dive inside of a Material Library node, Material Builder nodes and tools are available. This helps the VOP network mirror the USD data more accurately. It also makes it easier to keep the tab menu from offering an overwhelming number of options, most of which are incompatible with one another.
Builder Quickstart ¶
-
Create a Material Library LOP.
-
Dive inside of that node, create a Karma Material Builder.
-
Rename that subnet node to “quickstart_material”.
-
Go back up to the parent LOP network (i.e.
/stage
) -
Connect an Assign Material to the Material Library node created earlier.
-
On the Material Assign node, select some Primitives, then set Material Path to
/materials/quickstart_material
, to make the material assignment.
MaterialX Support ¶
Before getting too far into the details, it’s worth describing Karma’s support for MaterialX, and how that affects an artist building materials. Karma supports MaterialX shaders, but does not rely on MaterialX’s code-generation. Instead Karma reads the shader network of MaterialX nodes described in USD, and builds the material for the renderer on-the-fly. Because of this, Karma is able to supplement missing functionality in MaterialX, with Karma or USD Preview nodes.
Most of the time, artists should start with the Karma Material Builder, when building new materials for Karma. When a “pure” MaterialX network, with no custom Karma nodes or conventions, the “USD MaterialX Builder” will only offer up MaterialX nodes supported in the pure spec.
USD materials ¶
Materials in USD can target different renderers. Primitives can only have one material binding, but that single material can host various render contexts. These contexts can be shaders for different renderers or shading languages.
Karma supports a few render contexts. If a material has more than one supported context, Karma uses the following priorities:
Priority |
RenderContext |
Builder |
Example Nodes |
---|---|---|---|
1 |
|
VEX Material Builder |
|
2 |
|
Karma Material Builder |
|
3 |
|
USD MaterialX Builder |
|
4 |
|
USD Preview |
Note
While Karma XPU and CPU support mixing MtlX/Karma/Preview nodes, this is not typically supported by other render engines.
Material bindings ¶
Assigning materials to primitives in Solaris is straightforward. You can bind a material to a prim or GeomSubset using a Material Library or Material Assign node.
By default, the Material Binding Strength is Weaker Than Descendants. This means that bindings apply to all child prims, unless those child prims have their own material binding. Applying materials to ancestor prims, and setting the strength to Stronger than Descendants, can be used to override materials scene-wide.
Warning
Hydra may not override “weaker” materials on instances as one might expect. This behavior is expected to improve in coming versions of USD and Solaris. In the meantime, broadcasting material overrides via inherited class prims can replace materials on instances.
Material bindings in USD can also apply to only specific Purposes (USD render purposes represent different types of renders, such as previews, map generation, and final renders). By default materials apply to any purpose, but you can set a material to only bind in final renders, for example.
USD supports Collection-based material bindings, but at this point there aren’t a lot of workflow/performance advantages to strongly recommend that method. (When USD Collections can be defined as patterns, and/or Hydra supports instance-overrides via collection-based assignments, this will become a very powerful workflow.)
Building shaders ¶
-
Shader building for Karma using VOPs is mostly the same as it was for Mantra and other renderers in Houdini.
-
Material Library tries to create a USD Preview Surface from your material automatically; it works best with Principled Shader and MtlX Standard Surface. Sometimes it’s desireable to avoid creating the automatic Usd Preview material. You can disable the preview generation using the toggle in the Material Library node.
-
Textures can slow down GL viewers, particularly Storm (Pixar’s OpenGL Hydra delegate). If you are concerned with scalability, use
displayColors
anddisplayOpacity
in USD Preview shaders to color mid to background objects rather than using textures. -
Use the Collect VOP as the final node when building materials to make it easier to add displacement shaders, as well as manual USD Preview Surfaces or other shaders to the material.
-
You can use Parameter VOPs to create a “public” material interface. This makes it easier to edit materials in downstream LOPs, avoiding the need to edit the underlying shader graph. It also makes it possible to drive different shaders with the same parameter (such as the path to a texture map).
MaterialX ¶
-
If you need a pure MaterialX shader, which works everywhere UsdMaterialX is supported, start with a USD MaterialX Builder.
-
The Karma Material Builder simplifies creating Karma materials based on MaterialX. Inside this subnet, the ⇥ Tab menu is filtered to only show compatible Karma, USD Preview, and MaterialX nodes. This helps you avoid accidentally using VEX VOP nodes in your shader network.
-
You can use MaterialX nodes to drive the patterns on Karma Hair or other Karma-specific shaders.
-
Unlike Houdini’s Principled Shader, the MtlX Standard Surface node does not auto-bind its parameters to geometry attributes.
-
MaterialX shaders with this icon , and which have the
hmtlx
prefix, are implemented using pure MaterialX nodes, but are not part of the MaterialX standard distribution.
USD preview shader ¶
-
USD PrimVar reader is compatible with MaterialX nodes in Karma.
-
Until UsdMaterialX is supported by more render delegates, the USD Preview shaders are the most common/universal way to define a material.
-
For a strict USD Preview-only material, use the USD Preview Material Builder.
VEX ¶
-
VEX shaders only work with Karma CPU (not Karma XPU).
-
Instead of binding directly to
Cd
, use the Surface Color node in your shaders. This will fall back todisplayColor
primvars ifCd
isn’t found on the geometry. This makes VEX shaders easier to port from Mantra to Karma. -
Point Cloud or other geometry-lookup shaders should still work in Karma CPU, but they cannot access any primitives on the stage. They can only access
.bgeo
geometry files from disk.
Warning
Karma XPU does not support the Principled Shader. However the automatic preview shader feature on Material Library can make it seem like it does. Stats and logging information should clarify these situations, to avoid spending time debugging the wrong issues.
Primvars ¶
Attributes and properties encoded as primvars can be used to drive parameters on shaders of your materials. Any primvar interpolation type is supported, and the supported value types are the shader signatures on the node itself. In addition to the generic reader nodes, Karma supports the specific attribute readers included with MaterialX.
Shading Family |
Primvar Reader Nodes |
---|---|
MaterialX |
|
USD Preview |
|
VEX |
-
Both the MaterialX and USD Preview nodes can be used by Karma CPU and XPU
-
Volumes can be bound using the Primvar reader nodes from MaterialX
-
When reading primvars in a volumetric shader, only constant-interpolated primvars on the
density
field can be read. Constant primvars on other fields are ignored.
Material Properties ¶
Many of Karma’s render properties can be overridden at the geometry level. To make it easier to associate render properties with materials, The Karma Material Properties node lets users apply rendersettings via materials. The way these work, is the render properties are added as inputs to the material’s surface shader. Karma can read these inputs, and apply geometry properties as if the gprims themselves had the settings applied to them. Render Properties applied via material is weaker than those applied directly to the geometry.
Transmissive materials ¶
By default Karma uses some optimizations for transmissive materials, such as glass and water.
-
Fake caustics are enabled by default
-
Internal reflections are also disabled.
This can look fine in many situations, and is pretty fast. However true caustics and internal reflections can also be enabled to get a more physically correct result..
Nested dielectrics can also be setup using material or geometry properties, to render nested transmissive materials correctly.
Transmissive Geometry Render Properties
Emissive materials ¶
Non-light primitives can be made emissive, so they contribute illumination at render time. The following shaders support emission:
|
MaterialX |
|
|
USD Preview |
|
|
VEX |
|
Creating an emissive shader is usually just the first step. Sampling emissive geometry isn’t as efficient as sampling an actual light primitive. Karma has special render properties, that can improve the sampling of emissive geometry. These properties can be set on the material, or on the geometry objects.
The Karma Material Properties sets render propeties on the Material. While a Render Geometry Settings node can tell Karma to treat certain geometry primitives as light sources. Some additional parameters are also available to control the look and quality of the emissive geometry.
Emissive Geometry Render Properties
AOVs ¶
Material-defined render vars (AOVs) are not defined as part of USD yet. Until such time, Houdini/Karma provide a custom solution to set these up. This workflow is much more streamlined compared to past released of Solaris.
See Karma AOV 2.0 for more details.
Custom Nodegraph Definitions ¶
Complex bundles of MaterialX shade prims can be converted into atomic node definitions. You may find this useful if your HDAs are producing lots of UsdShade prims or long processing times by Material Library or Karma.
This is currently a technical process, but can be valuable workflow for studios or advanced users. Here are roughly the steps you would need to follow or automate:
-
Convert the subnet-based VOP HDA to a MaterialX definition using
$HHP/vop2mtlx.py
. This is the source HDA, but is not the HDA artists would use directly, so it doesn’t need to live in a standard otls folder. The user-facing HDA will be produced later. -
That .mtlx source file is then post-processed by two other tools:
-
$HHP/mtlx2karma.py
- outputs the karmaNodeGraph.json file necessary for Karma to render these shaders correctly; this should be added to HOUDINI_PATH or user preferences directory -
$HHP/mtlx2hda.py
- produces the user-facing output HDA, should be added to any otls folder on HOUDINI_PATH or user preferences directory
-
-
Add the output hda file to
$HOUDINI_USER_PREF_DIR/otls
andkarmaNodeGraph.json
files to$HOUDINI_USER_PREF_DIR
. -
Materials using your custom shader should now render with Karma.
An example can be found at $HFS/houdini/help/files/karma_user_guide/custom_nodegraphs
. Copy that folder to a writeable location, and start Houdini from within the _custom_nodegraphs_ folder. Opening result.hip
should render a green and red cylinder in the Viewport with Karma, as seen in this image to the left; custom_nodegraphs.hip
has the steps used to produce the custom node.
Here are some additional tips:
-
The
--help
output of each script has lots of valuable information -
Only the first signature is exported to MaterialX by default; you need to pass
--all_signatures
tovop2mtlx.py
if your shader has multiple signatures -
Your development HDA may not show up in the tab menu by default; you can fix this by setting VopNet Mask to
MaterialX
under Node in Type Properties. It’s not necessary to do this for the user-facing HDA. -
You can tag inputs to read geometry properties implicitly using
sidefx::mtlx::defaultgeomprop
; the available tokens are listed here:-
Note that for
texcoord
inputs, using the tokenUV0
will bind to USD’s defaultprimvars:st
-
Using
kma_*
nodes will not work, as these are not MaterialX shaders -
Use the
--library-path
flag onvop2mtlx.py
, if your graph is built using other custom node definitions.
Next steps ¶
For more information on building shaders and materials for Karma, see Using MaterialX in Solaris.
Next Textures