Log inGet started
World

Builtin Library

Branchmain
Branchesmainpublish
Commit61a33237e0

README.md

terrain_scatter_place

Turns one tile's density channel into instance transforms in the shared pool renderer.mesh.drawInstanced reads.

One thread per candidate site, not per cell.

Sites are world-anchored

The sites are a grid of spacing world metres running from the field's minimum corner. A site belongs to exactly one tile — the one its centre falls in — so the same field produces the same sites whatever the tiling, whatever the resolution, and however much of the field is being re-evaluated.

A site carries an instance with probability density * spacing^2. That is what makes the density channel mean instances per square metre: summed over the sites of an area, the expected count is the integral of the density over it.

One site carries at most one instance, so 1 / spacing^2 is the densest cover a spacing can express. terrainScatter derives the spacing from the density the rule actually reaches rather than letting a caller find that ceiling by hitting it.

Determinism

Acceptance, the jitter inside the site, the yaw and the scale are all hashes of the site's integer grid indices and the seed. The instance a site carries is therefore the same instance every run: a reload does not reshuffle a forest, and re-evaluating one corner of the field leaves the rest of the population exactly where it stood.

Slots in the pool are handed out by an atomic, so which slot an instance lands in varies between runs. The set of instances and each one's matrix do not.

Overflow is a resize, not a short forest

When the accepted count runs past capacity the counter keeps counting and the extra instances are not written. The total it reports is what the caller grows the pool to before running the pass again, which is how a population that grew past its reservation ends up complete rather than silently clipped.

The matrix layout

Column-major 4x4, four vec4 columns per instance, tightly packed — the layout a vertex shader reads as array<mat4x4<f32>>. Columns 0..2 are the basis scaled by the instance's scale; column 3 is the translation.

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 instance transforms. Where a population may grow is already decided by the density channel it reads, and terrain_scatter_density is where a mask shapes that. The separation is on purpose.