Log inGet started
World

Builtin Library

Branchmain
Branchesmainpublish
Commitdd348ac6c3

README.md

Scatter

Strews copies of one shape over the surface of another, each with its own turn, lean and size.

Both the surface and the thing scattered are inputs, so this covers rocks on a hillside, crates on a deck, bushes along a bank or rubble across a floor: wire it a different source and it is a different field.

It makes points on the surface (points.on_surface, area-weighted), gives every point its own random yaw, lean and scale (instances.randomize_transform), and places the source on those points (instances.on_points). The transform is read from the same point cloud the instances sit on, so each copy takes the pose of its own point.

Inputs

InputTypeDefaultWhat it does
surfaceGeometrynoneWhat the copies land on. Points are area-weighted, so a bigger face gets proportionally more.
sourceGeometrynoneThe shape being copied.
countInt200How many copies.
seedInt1Changes the arrangement. The same seed always gives the same field.
scaleMinFloat0.8Smallest per-copy size multiplier.
scaleMaxFloat1.4Largest per-copy size multiplier. Equal to scaleMin means uniform.
tiltFloat8.6Degrees of random lean off vertical, 0 to 90. 0 stands every copy upright.

Output

instances: a population, the points each carrying the source as its Mesh, with orient and scale from the random transform. A Generator draws it as one hardware-instanced draw call per source; instances.realize merges it into a single Geometry.

Calling it

The graph is built with proc.graph("Scatter"), and its declared inputs are the inputs of a call. Through its asset ref, ref:eval("instances", { inputs = { ... } }) evaluates it with inputs given, and in a graph built with proc.graph, g:node("<id>", ref, inputs, params) calls it as a node, with inputs the wired node ids and params the rest:

local proc = require("@builtin::systems.procgen.proc")
local ref = asset.resolve("@builtin::systems.procgen.examples.Scatter", "procGraph")
local g = proc.graph("rockyField")
g:node("ground", "mesh.grid")
g:node("rock", "mesh.box")
g:output("instances", g:node("rocks", ref, { surface = "ground", source = "rock" }, { count = 20 }))
local rocks = proc.eval(g, "output:instances")

The name Scatter that g:node("<id>", "Scatter", ...) resolves is the node examples/ops/Scatter.procNode, which declares the same name and holds the same graph.