Skip to content

Instancer Nodes

Instancer nodes are terminal nodes that consume Point data and spawn GameObjects in the scene. They do not output any port data. All nodes in this category use the purple node color (#993399).


Common Concepts

Transform Offsets

All instancer nodes support a set of base transform fields that are applied on top of each point's existing transform matrix:

FieldTypeDefaultDescription
baseOffsetVector3(0, 0, 0)Local position offset applied in the instance's rotated space.
baseRotationVector3(0, 0, 0)Euler rotation offset in degrees applied after the point's own rotation.
baseScaleVector3(1, 1, 1)Scale multiplier. Use this to correct FBX import scale differences.

Weighted Instancer does not have a baseScale on the node — each WeightedPrefab entry has its own baseScale instead.

Material Property Mapping

Prefab Instancer and Weighted Instancer both expose a materialProperties array of PPGMaterialPropertyMapping entries. Each mapping reads a point attribute and writes it to a named MaterialPropertyBlock shader property on all Renderer components of the spawned instance.

This allows per-instance shader variation (e.g. driving a tint colour from the point's color field, or passing a noise attribute to a wind sway shader) without requiring separate prefab variants.

Parent To Component

When parentToComponent is true (the default), spawned GameObjects are parented under the PPGComponent's Transform. This allows the component to track and clean up instances on re-generation or scene unload via ManagedResources.


Prefab Instancer

Category: Instancers
Description: Instantiates a single prefab at every input point.

Ports

DirectionNameType
InputInPoint

Settings

Prefab

FieldTypeDefaultDescription
prefabGameObjectnullPrefab to instantiate at each point. A warning is logged if unset.

Instantiation Mode

FieldTypeDefaultDescription
modeInstancingModeGameObjectGameObject: standard Instantiate. StaticBatching: instantiates normally, then calls StaticBatchingUtility.Combine on the parent after all instances are placed.

Transform Offsets

FieldTypeDefaultDescription
baseOffsetVector3(0, 0, 0)Position offset in the instance's rotated local space.
baseRotationVector3(0, 0, 0)Euler rotation offset in degrees.
baseScaleVector3(1, 1, 1)Scale multiplier.

Parenting

FieldTypeDefaultDescription
parentToComponentbooltrueParent spawned GameObjects under the PPGComponent transform.

Material Properties

FieldTypeDefaultDescription
materialPropertiesPPGMaterialPropertyMapping[]Empty array ([])Per-instance material overrides. Each entry maps a point attribute to a shader property name via MaterialPropertyBlock.

Tips

  • StaticBatching mode is intended for prefabs with static meshes. It reduces draw calls but prevents per-instance transform changes at runtime after generation.
  • Cancellation is checked every 64 instances during execution to keep the editor responsive.
  • When parentToComponent is false, instances are not tracked by ManagedResources and must be cleaned up manually.

Prefab Graph Instancer

Category: Instancers
Description: Instantiates prefabs at each input point and, if the prefab contains a PPGComponent, automatically executes its inner graph.

This node enables nested procedural generation: the outer graph places parent prefabs, and each prefab's own graph generates content relative to its position.

Ports

DirectionNameType
InputInPoint

Settings

Prefab

FieldTypeDefaultDescription
prefabGameObjectnullPrefab to spawn. If it has a PPGComponent, that component's graph is automatically executed after instantiation.

Transform Offsets

FieldTypeDefaultDescription
baseOffsetVector3(0, 0, 0)Position offset in the instance's rotated local space.
baseRotationVector3(0, 0, 0)Euler rotation offset in degrees.
baseScaleVector3(1, 1, 1)Scale multiplier.

Parenting

FieldTypeDefaultDescription
parentToComponentbooltrueParent spawned GameObjects under the PPGComponent transform.

Binding Resolution

FieldTypeDefaultDescription
bindingResolveModePPGBindingResolveModeByNameThenTypeHow inner graph binding slots are resolved to components on the spawned instance. See enum table below.

PPGBindingResolveMode enum

ValueDescription
NoneNo automatic resolution. Bindings must already be configured inside the prefab.
ByNameThenTypeSearches for a child GameObject matching the slot name first (via Transform.Find), then falls back to GetComponentInChildren by type.
ByTypeOnlyResolves exclusively via GetComponentInChildren by the slot's binding type.

Inner Graph Execution

When a spawned instance contains a PPGComponent:

  1. The instance is created inactive to prevent Start() from triggering an early Generate() call.
  2. GenerateOnStart on the inner component is set to false.
  3. A deterministic seed is derived from WangHash(point.seed ^ contextSeed) and assigned to innerComp.Seed.
  4. Bindings are resolved according to bindingResolveMode.
  5. The instance is activated, Physics.SyncTransforms() is called to ensure colliders are ready, and innerComp.Generate() is invoked.

If the inner graph throws, a warning is logged for that specific point and execution continues with the remaining points.

If the prefab has no PPGComponent, the node falls back to behaving like a standard Prefab Instancer (activate and continue).

Recursion Limit

The node guards against infinite recursion. If nesting depth exceeds 4 levels, an error is logged and the node returns false. Avoid circular prefab graph references.

Tips

  • Inner graph seeds are deterministic: the same outer seed + point layout always produces the same inner layout.
  • ByNameThenType is recommended when prefabs have named sub-objects that match binding slot names (e.g. a Terrain child named "Terrain" matching a terrain binding slot).
  • A warning is emitted if a resolved binding target has no Collider component, since surface-sampling nodes (e.g. surface scatter) inside the inner graph will not function without a collider.
  • Spawned instances are tracked by the outer ManagedResources and are cleaned up when the outer component regenerates.

Weighted Instancer

Category: Instancers
Description: Instantiates from a list of prefab entries, selecting which prefab to spawn per point using weighted random, float-range attribute mapping, or direct integer indexing.

Ports

DirectionNameType
InputInPoint

Settings

Instantiation Mode

FieldTypeDefaultDescription
modeInstancingModeGameObjectGameObject: standard Instantiate. StaticBatching: combines all spawned meshes after placement via StaticBatchingUtility.Combine.

Selection

FieldTypeDefaultDescription
selectionModePPGWeightedSelectionModeRandomWeightAlgorithm used to pick an entry per point. See enum table below.
selectionAttributePPGAttributeSelectorDensityAttribute that drives selection in FloatRange and DirectIndex modes. Ignored in RandomWeight mode.

PPGWeightedSelectionMode enum

ValueDescription
RandomWeightPerforms a deterministic weighted random roll per point using WangHash(point.seed) ^ WangHash(contextSeed + pointIndex).
FloatRangeReads a [0, 1] float from selectionAttribute and maps it to weighted bands proportional to each entry's weight field.
DirectIndexReads an integer from selectionAttribute and uses it as a direct entry index (with modulo wrap-around).

Weighted Prefab Entries

entries is an array of WeightedPrefab structs:

FieldTypeDefaultDescription
prefabGameObjectnullPrefab to spawn for this entry. Entries with a null prefab are skipped.
weightfloat1.0Relative probability weight. Values are normalised internally to sum to 1.
baseScaleVector3(1, 1, 1)Per-entry scale multiplier applied to the spawned instance.

Transform Offsets (node-level)

FieldTypeDefaultDescription
baseOffsetVector3(0, 0, 0)Position offset in the instance's rotated local space.
baseRotationVector3(0, 0, 0)Euler rotation offset in degrees applied after point rotation.

Unlike the other instancer nodes, there is no node-level baseScale. Scale is controlled per-entry via WeightedPrefab.baseScale.

Parenting

FieldTypeDefaultDescription
parentToComponentbooltrueParent spawned GameObjects under the PPGComponent transform.

Material Properties

FieldTypeDefaultDescription
materialPropertiesPPGMaterialPropertyMapping[]Empty array ([])Per-instance material overrides mapped from point attributes to shader properties via MaterialPropertyBlock.

Consumed Attributes

When selectionMode is FloatRange or DirectIndex and selectionAttribute is a custom attribute, it is declared as consumed (IPPGAttributeConsumer).

Internal Weight Normalisation

Entry weights are normalised to a cumulative probability table at runtime:

cumulativeWeights[i] = sum(entries[0..i].weight) / totalWeight

The last entry is always clamped to exactly 1.0 to prevent floating-point drift. If totalWeight <= 0, a warning is logged and no instances are spawned.

Tips

  • In RandomWeight mode, each point's seed is combined with the graph's context seed and the point's index to produce a deterministic, reproducible selection even across multiple generate calls.
  • FloatRange mode is ideal for attribute-driven variety: e.g. use a Attribute Noise node to generate a density field, then map it to prefab bands (sparse undergrowth at low density, dense canopy at high density).
  • DirectIndex mode is useful when upstream nodes explicitly tag points with an integer category attribute created by a Create Attribute node.
  • StaticBatching mode requires parentToComponent = true; batching is performed on the parent GameObject after all instances are placed.
  • Parameter expose (SupportsParameterExpose) is disabled for this node because per-entry weight values are not individually exposable as graph parameters.

Procedural Placement Graph for Unity