Skip to content

Sampler Nodes

Sampler nodes either generate new point sets by reading external data sources (terrain heightmaps, meshes, textures) or annotate an existing point set with sampled values. They are found in the Samplers category of the node picker.

Unlike the pure generator nodes, most sampler nodes interact with Unity scene objects (Terrain, Colliders, Mesh assets, Texture2D). Refer to each node's Notes section for any asset import requirements.


Surface Sampler

Display name: Surface Sampler
Category: Samplers
Description: Generates points on physical surfaces by casting rays downward from a uniform XZ grid. Hits are recorded as output points with normals and steepness data.

Ports

DirectionNameTypeRequired
InputSurfaceSurfaceNo
OutputOutPoint

Settings

FieldTypeDefaultDescription
originVector3(0, 50, 0)Ray start position. Only the Y component is used as the vertical ray origin height; the X and Z of each ray origin come from the sampling grid.
maxRayDistancefloat100.0Maximum distance a ray travels before being discarded.
layerMaskLayerMaskEverything (~0)Physics layers the raycast can hit.
areaMinVector3(-10, 0, -10)Minimum XZ corner of the sampling grid, in local space relative to the PPG component.
areaMaxVector3(10, 0, 10)Maximum XZ corner of the sampling grid, in local space relative to the PPG component.
spacingfloat1.0Distance between adjacent ray origins in the grid. Minimum enforced: 0.01.

Output Point Attributes

Each successfully hit point has the following data written automatically:

AttributeValue
density1.0 (always)
transformRotation aligned to the hit surface normal (up = hit.normal).
steepness1 − dot(normal, Vector3.up). Flat horizontal surfaces → 0; vertical walls → 1.

Notes

  • When the Surface port is connected, only colliders from the connected PPGSurfaceData are hit. The layerMask acts as an additional filter on top.
  • When Surface is disconnected, raycasts hit any collider matching layerMask.
  • areaMin/areaMax are in the PPG component's local space; the node converts them to world space using the component transform before raycasting.
  • In Edit Mode, Physics.SyncTransforms() is called automatically so collider positions are current even without entering Play Mode.
  • Grid resolution = (areaMax - areaMin) / spacing + 1 per axis. Keep spacing reasonable to avoid excessive raycast counts in large areas.

Mesh Surface Sampler

Display name: Mesh Surface Sampler
Category: Samplers
Description: Samples points directly on mesh triangle surfaces using area-weighted random distribution. Accepts a Prefab or a single Mesh asset. No colliders or raycasting needed — works with any mesh topology.

Ports

DirectionNameTypeRequired
OutputOutPoint

Settings

Source

FieldTypeDefaultDescription
prefabGameObjectNonePrefab or scene GameObject to sample. All MeshFilter components in the hierarchy are collected and their meshes are sampled together as one combined surface.
meshMeshNoneStandalone mesh asset. Used as a fallback when prefab is not assigned.

Sampling

FieldTypeDefaultDescription
densityModePPGMeshSamplerDensityModePointsPerSquareMeterDetermines how the total point count is calculated.
pointsPerSquareMeterfloat10.0Points placed per square metre of mesh surface area (PointsPerSquareMeter mode). Min: 0.01.
fixedPointCountint1000Exact total point count, regardless of mesh size (FixedCount mode). Min: 1.
maxPointsint100000Safety cap applied after the mode calculation. Min: 1.

Normals

FieldTypeDefaultDescription
useFaceNormalsboolfalseWhen enabled, uses flat per-face normals instead of interpolated vertex normals. Recommended for faceted/low-poly meshes.

Output

FieldTypeDefaultDescription
densityfloat1.0Density value assigned to every generated point. Range 0–1.

Density Mode Reference

ModePoint count formula
PointsPerSquareMeterfloor(totalSurfaceArea × pointsPerSquareMeter), clamped to maxPoints.
FixedCountfixedPointCount, clamped to maxPoints.

Notes

  • All meshes (prefab children and standalone mesh) must have Read/Write enabled in their import settings. Non-readable meshes are skipped with a console warning.
  • Points are area-weighted: larger triangles receive proportionally more sample points for a uniform surface density.
  • When Prefab has multiple child meshes, all child transforms are baked into the prefab's root space before sampling so proportions are correct.
  • Each output point's rotation is aligned to the sampled surface normal.
  • Sampling runs in a Burst-compiled parallel job (PPGMeshSurfaceSampleJob).
  • This node uses the graph Seed for reproducibility. The same seed always produces the same distribution.

Terrain Surface Sampler

Display name: Terrain Surface Sampler
Category: Samplers
Description: Generates a grid of points directly on a Unity Terrain's heightmap surface by reading raw height data — no raycasting required. Significantly faster than Surface Sampler for large terrains.

Ports

DirectionNameTypeRequired
InputTerrainSurfaceNo
OutputOutPoint

Settings

FieldTypeDefaultDescription
spacingfloat1.0Distance between adjacent sample points in world units. Minimum: 0.1.
maxPointsint500000Safety cap on total generated points. When the computed grid exceeds this count, step sizes are scaled up automatically to fit. Min: 1.
filterHolesbooltrueWhen enabled, points that fall inside terrain holes are excluded from the output.
densityfloat1.0Initial density value for all generated points. Range 0–1.

Notes

  • When the Terrain port is connected, that terrain is used. When disconnected, Terrain.activeTerrain is used as a fallback; if no active terrain exists the node emits a warning and produces no output.
  • Output points are generated in the terrain's world space and then converted into the PPG component's local space.
  • Each point's rotation aligns to the terrain surface normal at that sample location.
  • Point positions sit exactly on the terrain surface height (no Y offset or approximation).
  • This node uses the graph Seed for reproducibility.
  • For runtime performance, prefer this node over Surface Sampler whenever the target surface is a Unity Terrain.

Terrain Sampler

Display name: Terrain Sampler
Category: Samplers
Description: Reads terrain data at each input point's XZ position and uses it to modify density or write metadata attributes. Supports layer paint weights, raw height, steepness, and terrain hole filtering.

Ports

DirectionNameTypeRequired
InputInPointYes
InputTerrainSurfaceNo
OutputOutPoint

Settings

Channel

FieldTypeDefaultDescription
channelPPGTerrainChannelLayerWeightWhich terrain data to sample. See the Channel Reference table below.
layerIndexint0Zero-based index of the terrain layer to sample. LayerWeight channel only.

Density

FieldTypeDefaultDescription
blendModeDensityBlendModeMultiplyLayerWeight channel only. Replace: sets point.density = layerWeight. Multiply: sets point.density *= layerWeight.
removeZeroDensitybooltrueWhen true, points whose density reaches 0 after sampling are removed from the output stream.

Attributes

FieldTypeDefaultDescription
writeLayerAttributesboolfalseLayerWeight channel only. When true, writes every terrain layer's weight as a separate float metadata attribute named TerrainLayer_0, TerrainLayer_1, etc.
attributeNamestring""Height / Steepness channels. Name of the float metadata attribute to write the sampled value into. Leave empty to skip the attribute write.

Channel Reference

ChannelData sampledOutput effect
LayerWeightWeight [0, 1] of layerIndex from the splatmapAdjusts point.density via blendMode. Optionally writes all layer weights as named attributes when writeLayerAttributes is enabled.
HeightWorld-space Y height of the terrain surfaceWrites value to the metadata attribute named attributeName. Point positions are not modified.
SteepnessTerrain steepness [0, 1] (0 = flat, 1 = vertical)Writes value to point.steepness and to the metadata attribute named attributeName.
HoleWhether the terrain has a hole at the point positionRemoves points that fall inside holes. No density modification.

Notes

  • When the Terrain port is connected, that terrain is used. When disconnected, Terrain.activeTerrain is used as a fallback.
  • Layer weight sampling runs in a Burst-compiled parallel job for performance.
  • The most common workflow is LayerWeight + Multiply + removeZeroDensity: points are retained only where the paint layer has weight, naturally masking placement to painted areas.
  • The Hole channel acts as a hard filter — points inside holes are always removed regardless of removeZeroDensity.
  • Multiple Terrain Sampler nodes can be chained: e.g. first filter by layer, then remove holes, then write height as an attribute.

Dynamically Created Attributes

When writeLayerAttributes is enabled, the node advertises the following attributes to downstream nodes at edit time:

Attribute nameType
TerrainLayer_0float
TerrainLayer_1float
TerrainLayer_Nfloat

When attributeName is non-empty (Height or Steepness channel), the node advertises:

Attribute nameType
(attributeName)float

Texture Sampler

Display name: Texture Sampler
Category: Samplers
Description: Samples a Texture2D at each input point's XZ position, mapped to a world-space rectangle, and writes the result to point density, point color, or a named metadata attribute.

Ports

DirectionNameTypeRequired
InputInPointYes
OutputOutPoint

Settings

Texture

FieldTypeDefaultDescription
textureTexture2DNoneTexture to sample. Must have Read/Write enabled in import settings.

Mapping

FieldTypeDefaultDescription
worldMinVector2(-10, -10)World-space XZ coordinate that maps to UV (0, 0). (Vector2.x → world X, Vector2.y → world Z.)
worldMaxVector2(10, 10)World-space XZ coordinate that maps to UV (1, 1).
clampUVbooltrueWhen true, UVs outside [0, 1] are clamped to the texture edge. When false, UVs tile (wrap).

Output

FieldTypeDefaultDescription
targetOutputTargetDensityDestination for the sampled value. See Output Target Reference below.
channelSampleChannelGrayscaleColor channel to extract when Target is Density or Attribute.
densityBlendDensityBlendModeMultiplyDensity target only. Replace: density = value. Multiply: density *= value.
attributeNamestring"TextureSample"Metadata attribute name used when Target is Attribute.
removeZeroDensitybooltrueDensity target only. When true, points with density <= 0 after sampling are removed.

Output Target Reference

TargetBehaviour
DensityExtracts channel from the pixel and writes it to point.density using densityBlend.
ColorWrites all four RGBA channels of the pixel directly to point.color (float4). channel is ignored.
AttributeExtracts channel from the pixel and writes it as a float to the metadata attribute named attributeName.

Sample Channel Reference

ChannelValue extracted
Redcolor.r
Greencolor.g
Bluecolor.b
Alphacolor.a
GrayscalePerceptual luminance (color.grayscale)

Dynamically Created Attributes

When Target is Attribute and attributeName is non-empty, the node advertises:

Attribute nameType
(attributeName)float

Notes

  • Sampling uses nearest-neighbour pixel lookup (Texture2D.GetPixel). No bilinear filtering is applied.
  • worldMin.y and worldMax.y represent the world Z axis, not the Unity Y axis.
  • The texture must have Read/Write enabled; a runtime error occurs otherwise.
  • Use the Color target with a gradient texture to assign per-point color data for downstream scatter nodes that support color variation.

Volume Sampler

Display name: Volume Sampler
Category: Samplers
Description: Generates points within a 3D axis-aligned bounding volume using either a regular grid or a uniform random distribution. Useful for placing objects inside enclosed spaces such as caves, rooms, or volumetric effects.

Ports

DirectionNameTypeRequired
OutputOutPoint

Settings

Volume

FieldTypeDefaultDescription
volumeMinVector3(-5, 0, -5)Minimum (bottom-back-left) corner of the sampling volume.
volumeMaxVector3(5, 5, 5)Maximum (top-front-right) corner of the sampling volume.

Sampling

FieldTypeDefaultDescription
modeSampleModeGridGrid: uniform 3D grid. Random: uniformly-distributed random points.
spacingfloat1.0Spacing between grid points (Grid mode only). Minimum enforced: 0.01.
countint100Number of random points to generate (Random mode only). Minimum: 0.
densityfloat1.0Density value assigned to every generated point. Range 0–1.

Sample Mode Reference

ModeBehaviour
GridFills the full AABB from volumeMin to volumeMax inclusive, stepping by spacing along all three axes. Point count ≈ ((vMax - vMin) / spacing + 1)³.
RandomPlaces exactly count points with uniformly-random positions within the AABB. Uses the graph Seed for reproducibility.

Notes

  • Set volumeMin.y == volumeMax.y to generate a flat 2D distribution at a fixed height (equivalent to a horizontal plane sampler).
  • Grid mode is deterministic and does not use the seed; Random mode uses the graph Seed.
  • Output points are in the PPG component's local space. If the component is moved or rotated, placement adjusts automatically.
  • There is no built-in maxPoints cap for Grid mode — keep spacing reasonable to avoid generating millions of points over large volumes.

Procedural Placement Graph for Unity