Builtin Library
- ..
- README.md2.6 KB
- bindings.yaml1.8 KB
- shader.wgsl7.6 KB
README.md
terrain_scatter_density
Evaluates one scatter rule into a density channel: instances per square metre at every cell of one tile.
The unit is what makes a rule portable. An author asks for one tree per fifty square metres and gets that count whether the field is sampled at half a metre or at four, and whether the terrain is 512 m across or 4 km.
The rule inputs are the material stack's inputs
| Input | Where it comes from |
|---|---|
| height | the surface channel's own value, world metres |
| slope | the angle of its gradient, radians |
| curvature | its laplacian, 1/m — positive in gullies, negative on ridges and crests |
| mask | a co-registered raster, multiplied in or subtracted out |
| noise | gradient FBM over world position, so a forest edge is not a contour line |
Each band contributes a weight in 0..1 and the weights multiply. A rule that
sets one band and leaves the rest open is exactly that one band, so an author
who understands one understands all of them.
The density written is the peak density times the product of the weights.
The region
atX/atZ, radius and falloff bound where the rule applies at all, in world
metres. A radius of zero covers the whole field — what a ground cover
wants. Outside the region the shader writes nothing, so a second rule's density
on that cell stands.
The mask slot
maskMode picks what the mask raster does:
| mode | effect |
|---|---|
| 0 | multiply — the rule applies only where the mask is painted |
| 1 | subtract — the rule is kept OUT of where the mask is painted |
| 2 | none — the binding is not read |
Subtract is how an authored place op's clearing keeps a scattered forest
out of the ground a landmark stands on: the placement writes its footprint into
the placement channel and the scatter rule subtracts it.
A binding has to point somewhere, so at mode 2 the caller binds the height channel into the mask slot and the shader never reads it.
One thread per cell, apron included. The cell's world position comes from the field-wide cell index and the field's minimum corner, so a cell reached as one tile's apron resolves to the same density as the same cell reached as its neighbour's interior.
The op contract's mask
This kernel carries no op_mask / op_common. Those bind the mask every op
that writes GROUND is scaled by, and this one writes a density channel — it has
the mask binding above, with modes and a gain of its own, which is the mask a
scatter rule reads. The two are separate surfaces on purpose.