Talos docs

Foliage presets

Since 0.7Changed in next

Plant a scene's terrain with a named plant community in one call:

Plain text

Plant a scene's terrain with a named plant community in one call:

foliage.preset {scene, preset: "meadow", area: [-100, -100, 100, 100]}

The same from a shell: argus-agent foliage-preset --scene scenes/main.scene.json --preset meadow --area -100,-100,100,100 (--dry-run answers without writing; --help lists the presets).

The presets

PresetWhat it plantsGround cover it brings
meadowopen grassland, the odd lone oak or birch, clumps of shrubsmeadow
roadside-vergeshrubs from 2 m off the roads' edge, trees from 8 m, over meadow grassmeadow
pine-forestmountain pine, fir and some spruce, snags, a low shrub layerforest-floor
broadleaf-woodoak and birch woodland, a shrub layer, fernsmeadow-forest
temperate-forestmixed oak and birch woodland: saplings, a shrub layer, ferns, fallen logs, stumps and standing dead woodmeadow-forest
meadow-farmlandlone field oaks and birch, hedgerow shrubs in clumps, seeding grass tufts and wildflowersmeadow

Each preset is data, crates/flora-scatter/presets/<name>.json: terrain scatter ops using only the op's existing fields, the ground-cover preset to pair them with, a variant cap per op and a budget. Every preset keeps off the scene's roads (the edge ground cover leaves bare): the verge's shrubs 2 m and trees 8 m, the others' trees 3 m and shrubs and ferns 1 m.

A project's own presets

A preset of your own is the same data in the project, foliage/presets/<name>.json, and foliage.preset takes its name like a built-in's. define writes the file and plants it in one call:

foliage.preset {scene, preset: "my-wood", area: [0, 0, 200, 200], define: {
  summary: "Small spruces over forest floor.",
  groundCover: "forest-floor",
  ops: [{ op: "scatter", id: "my-wood.trees", name: "my-wood.trees", asset: "spruce.project_small",
          perHectare: 40, minSpacingM: 4, scale: [0.9, 1.1], competes: "canopy", collider: "none", cullDistanceM: 200 }]
}}
  • The name is lowercase letters, digits and hyphens, and not a built-in's. Every op is a scatter op whose id starts with <name>..
  • An op's asset is a template id (the project's own templates in foliage/templates/ first, which foliage.generate's saveTemplate writes, then the built-ins), a .foliage.json path, or recipe JSON. assets: [{asset, weight}] mixes several.
  • summary, groundCover (default meadow-forest), areaM, budget and variants are optional. A preset without a budget is not judged against one: the answer's budget is null and it is never overBudget.
  • After that, foliage.preset {preset: "my-wood", area} plants it anywhere, and editing the file changes what the next call plants. Reverting the defining call takes the file back with the planting.

Arguments

  • area: [minX, minZ, maxX, maxZ] in scene metres; it should lie on the scene's terrain.
  • seed: optional, default 1. The same scene, preset, area and seed give the same bytes.
  • scene: optional; the open scene when absent. The scene needs a terrain entity (terrain.create).
  • dryRun: cook and answer, write nothing.

What it writes

  • One foliage entity fp-<preset> at the terrain's origin (a layer lists at most 32 prototypes, so a preset with more adds fp-<preset>-layer-2, -layer-3, ...). Under it, one instancedMesh entity fp-<preset>-<n> per (op, model), with its .instances file beside the scene. All of them carry the tag foliage-preset:<preset>.
  • One glb per model in the scene's assets/foliage-preset/ (<template>.v<variant>.a<age>.glb), declared once as the asset fp-<stem>. The models are shared by every scene in that folder and rewritten only when their bytes change.
  • The preset's groundCover on the terrain, only when it has none.
  • Trees get colliders (a kart hits them); shrubs and ferns get none. Trees cull at 300 m. Shrubs cull at 150 m in meadow and roadside-verge, 80 m in pine-forest, and 70 m (ferns too) in broadleaf-wood: near the camera, the understory is most of a wood's drawn triangles.

Re-running and undo

  • A re-run REPLACES that preset's plants in that scene (it finds them by tag); it never plants twice. Other presets and every other entity stay. Two different presets over one area both plant.
  • With no editor on the scene it is one change: revert with its changeId takes it back, including the models it created. With the scene open in the editor, the editor's undo takes the scene back.

Budget

The answer gives instances, models (each one instanced draw) and triangles (full detail, over every instance) against the preset's budget, scaled to the area. overBudget says what is over. Each budget is 30% above the worst of four seeds over the documented 200 m square:

PresetInstancesModelsTriangles
meadow250113.8M
roadside-verge267134.0M
pine-forest332195.0M
broadleaf-wood597155.6M

Draws. A model draws as about two draw groups (measured headless on a kart scene: 88 models added 168 groups), so a preset costs about twice its models in draws. To keep that low, a preset caps the variants each op draws (variants in its file, op id -> cap): trees use 2 of their template's 8 variants, shrubs and ferns 1. The cap folds a placement's variant (v % cap) after the cook, so positions and spacing are the cook's and only fewer models are cooked.

Triangles. GPU time follows the triangles drawn (about 0.4 ms per million on an RTX 3080 at 1080p), so the presets are tuned in their data to draw about 1.5M or fewer from a ground camera: trees grow in the younger half of their template's ages (ageRange 0-0.49), the heaviest templates are a small share of their op's mix, and density is set from the budget table above.