Building Your Own Decorations

How to author custom decorations: the constraints, the data model, and the design principles that keep them compilable and portable.

The four built-in decorations (Trunk Decoration, Surface Decoration, Cluster Decoration, Assembly Decoration) cover the common meshing cases. When they don't fit (custom meshing logic, a specialised proxy decoration, a debug visualisation overlay, a decoration that consumes a project-specific attribute), the way forward is to author your own decoration on top of Core Decoration.

This is a technical workflow. The constraints come from Natsura's compiled-graph runtime: decorations are stored and executed as compiled SOP networks, which forces a particular discipline around how nodes are wired and how parameters are passed. The payoff is portability (a custom decoration can be saved as geometry and loaded into another scene) and performance (compiled execution is cheaper than ad-hoc SOPs at cook time).

For the broader system this fits inside, see Decorations.

When to build your own

Cases the four built-in decorations don't cover:

  • A specialised proxy decoration for gameplay collision or LOD that needs custom geometry per internode.
  • A debug visualisation overlay (markers, vectors, frame axes) tied to specific tree attributes.
  • A decoration that consumes a project-specific attribute (a damage attribute, a per-internode infestation flag, a custom stress tensor) and routes its output accordingly.
  • A meshing approach for an organ that none of the standard decorations handle directly (fruit, thorns, spines, distinct cap geometry).

If the built-in decorations cover the case but at the wrong density or with the wrong parameters, a custom decoration is overkill; lean on the existing parameter surfaces first.

What a decoration is, technically

Recap from Decorations:

  • A decoration is a compiled SOP graph stored as geometry, so it can be invoked later by Simulate.
  • The graph is portable: it can be saved (for example as bgeo) and loaded into another scene and still evaluate.
  • Decoration parameters are passed in as geometry primitives (similar in spirit to Mapping), so parameter changes don't trigger recompilation.
  • VEX inside the decoration reads the primitives and turns them into attributes that drive verbs (Sweep, Copy, Deform, and so on).

Each of these properties imposes constraints on what you can put inside a custom decoration.

The constraints

Compilation

The compiled-graph runtime requires that the network compile to a self-contained, attribute-driven structure. Changing the structure (adding or removing nodes) forces a recompile and reattachment. Parameter changes do not, because parameters arrive as primitives rather than as direct UI references.

The practical rule: no relative channel references to regular SOP nodes inside the compiled graph. A reference to ../foo/value will break when the graph is loaded somewhere else. Drive behaviour via attributes and VEX instead.

Verbs and VEX

Most native Houdini verbs (Sweep, Copy, Deform, Resample, and so on) cooperate with the compiled-graph framework. Non-verbs and non-compilable nodes are less cooperative; they either won't compile or will compile in a way that loses portability.

Practical rule: work with verbs and VEX. When you reach for a node that isn't a verb, check whether the same effect is achievable through a verb plus attribute setup.

Parameters as primitives

To keep recompilation cheap, decoration parameters are not direct UI links. They are passed in as geometry primitives. VEX inside the decoration reads them with primuv() or parameter-dictionary calls, then writes attributes that drive the verbs.

This is the same pattern used for Mapping parameters. The decoration's UI on the outside looks like a normal parameter pane; what's happening underneath is a primitive-based handoff.

Starting from Core Decoration

Core Decoration is the template. The expected shape:

  • Input 0: Graph. The growth graph carrying the skeleton and its attributes.
  • Output: Graph. The graph with your decoration instructions appended, ready for the next node downstream or for Simulate to execute.

Inside the wrapper, you author the SOP network that consumes the Natsura skeleton and attributes and produces the meshes you need. The deferred-generation pattern means your network doesn't produce geometry directly; it produces instructions that Simulate executes later, in the right order, with the right context.

Design principles

  • Attribute-driven, not node-coupled. Read attributes from the input graph. Write attributes onto your intermediate streams. Use those attributes to drive verb parameters.
  • Read primitives in VEX, write attributes, drive verbs. This is the standard pattern. Parameter primitives enter the network, VEX translates them into per-point or per-internode attributes, verbs read those attributes to do the work.
  • Avoid non-compilable nodes. When in doubt, check whether the node has a verb equivalent.
  • Avoid relative channel references. Anything that depends on a specific node path will break the portability promise.

Looking forward

The compiled-SOP-graph approach is the current authoring path. Longer-term, authoring APEX graphs directly for decorations is planned, which will let APEX users skip the SOP-side compilation discipline. The constraints above will still apply where they reflect the fundamental compiled-execution model; the authoring surface will change.

More templates and worked examples will follow as the custom-decoration pattern matures. Track the recording-prompts queue.

  • Decorations (concept). The broader decoration system that custom decorations sit inside.
  • Core Decoration. The template you start from.
  • Mapping. The sibling framework for scalar parameters via primitives, which custom decorations rely on.
  • Wrangle. The artist-facing VEX surface, useful for prototyping the attribute logic that your decoration will codify.