Houdini Houdini

Building a material library you can actually reuse

Houdini makes it easy to build a beautiful material and surprisingly easy to never see it again. The difference between a folder of shaders and a library is three decisions — where materials live, how they are packaged, and how they reference their textures.

Every Houdini artist has rebuilt the same scuffed metal more than once. Not because it is hard, but because the version from four months ago is inside a hip file, in a matnet, pointing at textures on a drive letter that no longer exists.

Decision one: where materials live

Houdini gives you two authoring contexts and they do not share materials. Choosing deliberately, once, avoids a lot of later confusion.

/obj — Material Network

A matnet holding a Redshift, Arnold, Karma or Principled builder. Texture nodes plug into the shader; the material is assigned via a Material SOP or the object's material parameter. Fewer moving parts, faster to iterate, and everything stays inside the hip file.

Right for look-dev, for personal work, and for anything rendering straight out of Houdini without a USD stage.

/stage — Material Library LOP

A Material Library LOP containing a MaterialX subnet or a renderer-specific builder, bound with an Assign Material LOP. The material becomes part of the USD stage, which means it travels with the asset rather than with the scene file.

Right when the output is a USD layer, when another department consumes the asset, or when you want materials to be part of the asset definition rather than the shot.

The practical rule

If the material describes the thing, author it in /stage so it travels with the asset. If it describes this shot's look, /obj is fine and faster. Most studio libraries end up in /stage; most personal libraries are perfectly happy in /obj.

Decision two: how materials are packaged

Three levels of durability, in increasing order of setup cost.

01Shelf tools

Use whenA handful of materials, personal use, right now.

HowDrag a material node onto a shelf tab. Houdini stores the node as a script you can drop into any scene.

LimitNo parameter interface, no versioning, and updating the original does nothing to copies already placed.

02Gallery and palette entries

Use whenA growing personal or small-team library you want to browse.

HowSave materials into a gallery file so they appear in a browsable palette, with a thumbnail and a name.

LimitStill copies rather than instances — a fix does not propagate to shots that already used it.

03Digital assets (HDAs)

Use whenA studio library, or anything you expect to maintain for more than a year.

HowWrap the material network in an HDA with a promoted parameter interface. Version the definition and put it on a shared path so every artist loads the same one.

LimitReal setup cost, and someone has to own the definitions. Worth it exactly when more than one person depends on them.

The jump worth understanding is between two and three. Galleries copy; digital assets instance. With HDAs, fixing a normal-map polarity bug in the definition fixes it in every shot that references it. With a gallery, you fix it once and then find forty copies that still have it.

Decision three: how textures are referenced

This is the one that causes the most pain and takes the least effort to get right.

file parameter
✗ C:/Users/fabian/Downloads/metal_scuffed_diff_4k.png
  breaks on the farm, on a colleague's machine, after any reorganise

✓ $HIP/tex/metal_scuffed_diff_4k.png
  travels with the scene file — good for shot-specific textures

✓ $JOB/lib/metal_scuffed_diff_4k.png
  travels with the job — good for shared project assets

✓ $TEXLIB/metal/metal_scuffed_diff_4k.png
  your own variable, set once per workstation — good for a permanent library

That last pattern is worth adopting for a real library. Define a variable pointing at your central texture library, set it in houdini.env or your studio's startup, and reference everything through it. The library can then move to a different drive or a NAS and nothing breaks — you change one variable rather than several hundred file parameters.

Keep textures out of the material package itself. Materials are small and cheap to rebuild; texture sets are large and shared between many materials. Coupling them means the same 4K set is duplicated per shot, which is how a 200 GB library quietly becomes 2 TB.

MaterialX, for a library meant to last

If you are building something you want to still use after your next renderer change, MaterialX is the best bet available. It renders natively in Karma, carries into USD pipelines, and is not owned by one vendor.

Channel Node chain Input on mtlxstandard_surface Colour space
Base colour mtlximage base_color srgb_texture
Roughness mtlximage specular_roughness raw
Metalness mtlximage metalness raw
Normal mtlximage → mtlxnormalmap normal raw
Displacement mtlximage → mtlxdisplacement displacement output raw
Opacity mtlximage opacity raw

One row in a different colour and the rest amber — the same colour space rule that applies everywhere. Base colour carries the sRGB transform; everything else is data and loads raw. Set it on each mtlximage node's file parameter as you create it, not afterwards.

For Redshift and Arnold the structure is identical and the node names are not: a Redshift material builder with texture samplers and a Bump Map node, or an Arnold builder with image nodes into an aiStandardSurface with a normal_map. Displacement differs most — each renderer binds it differently and each has its own scale convention, so a height that reads correctly in Karma will not in Redshift.

A structure that works

$TEXLIB and the asset library beside it
texlib/                      $TEXLIB — textures, shared by everything
├─ metal/
├─ stone/
├─ wood/
└─ hdri/

otls/                        material HDAs, versioned
├─ mat_standard_surface.hda
└─ mat_layered_blend.hda

galleries/                   quick-access palette entries
└─ materials.gal

The separation matters: textures change rarely and are large, material definitions change often and are small. Keeping them apart means you can version the definitions aggressively without moving gigabytes around.

The part that stays manual

Even with all of the above in place, one job repeats forever: turning a newly downloaded texture set into a material network. Find the folder, create the builder, add an image node per map, set six colour spaces, route the normal through a converter, bind the displacement, name it.

It is ten minutes that feels like one, per surface, per renderer, indefinitely — and it is the most automatable thing in the entire workflow because every step is a deterministic consequence of the filenames. There is a full breakdown of what that automation involves in how automatic material creation works.

How Kiosk fits into a Houdini library

Kiosk does not replace your material library — HDAs and galleries remain the right home for materials you have authored and tuned. What it replaces is the manual step above: turning raw texture sets into a network.

It indexes your texture library folder in place, detects texture sets from their suffixes, and renders previews for everything including the EXRs and VDBs Houdini's own file browser shows as filenames. With a live session running, clicking a set builds the material network for whichever renderer is active — Karma via MaterialX, Arnold, Redshift or RenderMan — with colour spaces assigned per node and displacement bound where that renderer expects it.

Two Houdini-specific behaviours worth knowing. It detects whether you are in /obj or /stage and builds accordingly, rather than making you pick. And file references are written with $HIP and $JOB rather than absolute paths, so scenes stay portable to the farm without a cleanup pass.

Geometry caches, VDB volumes and your own scanned assets sit in the same library, which for Houdini work is usually the larger half.

The quickest test is to point it at your texture library and click one surface with a Houdini session open. Everything else on this page is worth doing regardless.

Download the free edition

windows 10 / 11 · free edition · how the Houdini plugin works

Questions

How do I save a material for reuse in Houdini?

There are three levels. Quickest is dragging a material node into the shelf, which stores it as a tool you can drop into any scene. More robust is saving it to a gallery or palette file so it appears in a browsable list. Most durable is wrapping it in a digital asset, which gives it a versioned definition, a custom parameter interface and one place to fix a bug for every shot that uses it.

Should I build materials in /obj or /stage?

Depends where the result is consumed. A Material Network in /obj is quicker for look-dev and for scenes that render straight out of Houdini. A Material Library LOP in /stage is right when the result becomes a USD layer, when other departments consume the asset, or when the material should travel with the geometry. They are not interchangeable — a material authored in /obj is not automatically available to a LOP network, which catches out a lot of people moving to Solaris.

What is the advantage of MaterialX in Houdini?

Portability. A MaterialX network built around mtlxstandard_surface renders natively in Karma and carries meaningfully to other MaterialX-aware renderers and to USD pipelines, rather than being locked to one vendor. If you are building a library intended to outlive your current renderer choice, MaterialX is the format with the best odds.

Why do my textures break when a scene goes to the farm?

Absolute paths. A file parameter recording C:/Users/you/Downloads/textures works until the scene is opened by anything that is not your workstation. Houdini expands $HIP to the folder containing the scene file and $JOB to the job root, so a path written with those stays valid when the file moves. Retrofitting this across hundreds of parameters is miserable, so it is worth being strict from the start.

Can one material library serve Karma, Redshift and Arnold?

Not as a single set of nodes, no. Each renderer wants its own builder, its own normal conversion and its own displacement binding. The realistic approach is either to commit to MaterialX and the renderers that speak it, or to keep the texture sets as the library and generate the renderer-specific network on demand — which is the approach automated tools take.

How do I organise the textures behind the materials?

Separately from the materials themselves, in a central library folder outside any single project, referenced with $JOB or an explicit library variable. Materials are small and cheap to rebuild; texture sets are large and shared across many materials. Coupling them means duplicating textures per shot, which is how a 200 GB library becomes 2 TB.

Related: Poly Haven in Houdini and how to build an asset library that lasts.