Appearance
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:
| Field | Type | Default | Description |
|---|---|---|---|
baseOffset | Vector3 | (0, 0, 0) | Local position offset applied in the instance's rotated space. |
baseRotation | Vector3 | (0, 0, 0) | Euler rotation offset in degrees applied after the point's own rotation. |
baseScale | Vector3 | (1, 1, 1) | Scale multiplier. Use this to correct FBX import scale differences. |
Weighted Instancer does not have a
baseScaleon the node — eachWeightedPrefabentry has its ownbaseScaleinstead.
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
| Direction | Name | Type |
|---|---|---|
| Input | In | Point |
Settings
Prefab
| Field | Type | Default | Description |
|---|---|---|---|
prefab | GameObject | null | Prefab to instantiate at each point. A warning is logged if unset. |
Instantiation Mode
| Field | Type | Default | Description |
|---|---|---|---|
mode | InstancingMode | GameObject | GameObject: standard Instantiate. StaticBatching: instantiates normally, then calls StaticBatchingUtility.Combine on the parent after all instances are placed. |
Transform Offsets
| Field | Type | Default | Description |
|---|---|---|---|
baseOffset | Vector3 | (0, 0, 0) | Position offset in the instance's rotated local space. |
baseRotation | Vector3 | (0, 0, 0) | Euler rotation offset in degrees. |
baseScale | Vector3 | (1, 1, 1) | Scale multiplier. |
Parenting
| Field | Type | Default | Description |
|---|---|---|---|
parentToComponent | bool | true | Parent spawned GameObjects under the PPGComponent transform. |
Material Properties
| Field | Type | Default | Description |
|---|---|---|---|
materialProperties | PPGMaterialPropertyMapping[] | Empty array ([]) | Per-instance material overrides. Each entry maps a point attribute to a shader property name via MaterialPropertyBlock. |
Tips
StaticBatchingmode 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
parentToComponentisfalse, instances are not tracked byManagedResourcesand 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
| Direction | Name | Type |
|---|---|---|
| Input | In | Point |
Settings
Prefab
| Field | Type | Default | Description |
|---|---|---|---|
prefab | GameObject | null | Prefab to spawn. If it has a PPGComponent, that component's graph is automatically executed after instantiation. |
Transform Offsets
| Field | Type | Default | Description |
|---|---|---|---|
baseOffset | Vector3 | (0, 0, 0) | Position offset in the instance's rotated local space. |
baseRotation | Vector3 | (0, 0, 0) | Euler rotation offset in degrees. |
baseScale | Vector3 | (1, 1, 1) | Scale multiplier. |
Parenting
| Field | Type | Default | Description |
|---|---|---|---|
parentToComponent | bool | true | Parent spawned GameObjects under the PPGComponent transform. |
Binding Resolution
| Field | Type | Default | Description |
|---|---|---|---|
bindingResolveMode | PPGBindingResolveMode | ByNameThenType | How inner graph binding slots are resolved to components on the spawned instance. See enum table below. |
PPGBindingResolveMode enum
| Value | Description |
|---|---|
None | No automatic resolution. Bindings must already be configured inside the prefab. |
ByNameThenType | Searches for a child GameObject matching the slot name first (via Transform.Find), then falls back to GetComponentInChildren by type. |
ByTypeOnly | Resolves exclusively via GetComponentInChildren by the slot's binding type. |
Inner Graph Execution
When a spawned instance contains a PPGComponent:
- The instance is created inactive to prevent
Start()from triggering an earlyGenerate()call. GenerateOnStarton the inner component is set tofalse.- A deterministic seed is derived from
WangHash(point.seed ^ contextSeed)and assigned toinnerComp.Seed. - Bindings are resolved according to
bindingResolveMode. - The instance is activated,
Physics.SyncTransforms()is called to ensure colliders are ready, andinnerComp.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.
ByNameThenTypeis recommended when prefabs have named sub-objects that match binding slot names (e.g. aTerrainchild named"Terrain"matching a terrain binding slot).- A warning is emitted if a resolved binding target has no
Collidercomponent, 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
ManagedResourcesand 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
| Direction | Name | Type |
|---|---|---|
| Input | In | Point |
Settings
Instantiation Mode
| Field | Type | Default | Description |
|---|---|---|---|
mode | InstancingMode | GameObject | GameObject: standard Instantiate. StaticBatching: combines all spawned meshes after placement via StaticBatchingUtility.Combine. |
Selection
| Field | Type | Default | Description |
|---|---|---|---|
selectionMode | PPGWeightedSelectionMode | RandomWeight | Algorithm used to pick an entry per point. See enum table below. |
selectionAttribute | PPGAttributeSelector | Density | Attribute that drives selection in FloatRange and DirectIndex modes. Ignored in RandomWeight mode. |
PPGWeightedSelectionMode enum
| Value | Description |
|---|---|
RandomWeight | Performs a deterministic weighted random roll per point using WangHash(point.seed) ^ WangHash(contextSeed + pointIndex). |
FloatRange | Reads a [0, 1] float from selectionAttribute and maps it to weighted bands proportional to each entry's weight field. |
DirectIndex | Reads 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:
| Field | Type | Default | Description |
|---|---|---|---|
prefab | GameObject | null | Prefab to spawn for this entry. Entries with a null prefab are skipped. |
weight | float | 1.0 | Relative probability weight. Values are normalised internally to sum to 1. |
baseScale | Vector3 | (1, 1, 1) | Per-entry scale multiplier applied to the spawned instance. |
Transform Offsets (node-level)
| Field | Type | Default | Description |
|---|---|---|---|
baseOffset | Vector3 | (0, 0, 0) | Position offset in the instance's rotated local space. |
baseRotation | Vector3 | (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 viaWeightedPrefab.baseScale.
Parenting
| Field | Type | Default | Description |
|---|---|---|---|
parentToComponent | bool | true | Parent spawned GameObjects under the PPGComponent transform. |
Material Properties
| Field | Type | Default | Description |
|---|---|---|---|
materialProperties | PPGMaterialPropertyMapping[] | 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) / totalWeightThe 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
RandomWeightmode, 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. FloatRangemode 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).DirectIndexmode is useful when upstream nodes explicitly tag points with an integer category attribute created by a Create Attribute node.StaticBatchingmode requiresparentToComponent = true; batching is performed on the parentGameObjectafter all instances are placed.- Parameter expose (
SupportsParameterExpose) is disabled for this node because per-entry weight values are not individually exposable as graph parameters.