Terrain-Aware Constraints
Nature doesn't put trees on cliffs. Constraints enforce reality's rules so your scatter looks right.
How Constraints Work
Every candidate scatter point is tested against all active constraints using AND logic. A point must pass every constraint to survive. Fail one, and it's rejected. This is how you keep trees off cliffs, rocks out of water, and flowers below the treeline.
Constraint Types
Slope Constraint
Rejects points where the terrain slope exceeds a maximum angle. Computed via 3-point gradient sampling — flat ground is 0°, a vertical cliff is 90°. Trees on a 45° slope look wrong. Set maxDegrees: 30 and they stay on walkable ground.
{
"type": "slope",
"maxDegrees": 30
}
Height Constraint
Rejects points below a minimum height or above a maximum height. Use this to keep vegetation out of water (min height above sea level) or below the snow line (max height below peaks).
{
"type": "height",
"minHeight": 0,
"maxHeight": 100
}
Exclusion Zone
Defines a circular area where nothing can be placed. Use this for building clearances, paths, sacred areas, or any region you want to keep clear. Points inside the circle are rejected.
{
"type": "exclusion",
"center": [50, 50],
"radius": 20
}
Density Falloff
Not a hard reject — instead, this constraint modulates placement probability based on distance from a center point. Objects are dense near the center and thin out toward the edges. Perfect for biome transition zones where forest gradually gives way to grassland.
{
"type": "density_falloff",
"falloffCenter": [0, 0],
"falloffRadius": 100
}
Constraint Parameters
| Constraint | Parameter | Default | Description |
|---|---|---|---|
| Slope | maxDegrees | 45 | Maximum terrain angle in degrees (0–90) |
| Height | minHeight | -∞ | Minimum terrain height for placement |
| Height | maxHeight | ∞ | Maximum terrain height for placement |
| Exclusion | center | [0, 0] | Center of exclusion circle [x, z] |
| Exclusion | radius | 10 | Radius of exclusion circle in world units |
| Density | falloffCenter | [0, 0] | Center of density gradient [x, z] |
| Density | falloffRadius | 100 | Distance at which density reaches zero |
Cross-Layer Exclusion
Beyond per-point constraints, Landscaper supports cross-layer exclusion — where placed objects from one layer become exclusion zones for another. Buildings placed first? Trees avoid them automatically.
This works via a spatial hash grid. When a higher-priority layer places its instances, those positions are registered. Lower-priority layers check the grid and reject candidates within minDistance of any previously placed object.
{
"id": "trees",
"priority": 10,
"excludesLayers": ["buildings", "roads"],
"minDistance": 5
}
Stack constraints to create realistic biomes. A forest layer with slope < 30°, height 10–80, and density falloff from center creates a natural-looking tree line that thins toward peaks and avoids steep terrain.
Evaluation Pipeline
- Generate candidates — Algorithm produces 2D points (x, z)
- Cross-layer exclusion — Remove candidates near higher-priority placements
- Per-point constraints — Test each surviving candidate against slope, height, exclusion
- Density filtering — Apply falloff probability to remaining candidates
- Sample terrain — Get Y height for each placed point