Enhancing terrain
Run the terrain diffusion pass over a section or a whole globe: models, adherence, coastline options, revert, and the working-resolution bake.
Enhancing is the terrain diffusion pass. It takes the rough heightmap you painted or imported and re-synthesises it at true physical scale, so a blocked-in ridge comes back with spurs, gullies and a drainage network that a satellite render can read. In the section editor the button is Generate and the dialog is Generate terrain. On the globe the same idea runs planet-wide as Enhance world terrain inside the Enhance world dialog.
What the pass does#
Dayside builds a conditioning field from your authored land heightmap plus its bathymetry, downsamples it to a coarse grid whose cell size is a fixed physical property of the model, and hands that grid to the terrain model. The model super-resolves each coarse cell into a 256 px block of relief. The result is then reconciled back to your datum: the sea level, the coastline anchor and the land peak come from your input, and the detail comes from the model.
Three behaviours are worth fixing in your head before you touch a control.
The conditioning is rebuilt from the authored heightmap and bathymetry on every run. It is never read back from the last generation's output. A second Generate is another pass over your authored terrain, not a pass over the previous result. Without this, each "fresh" generate would condition on the last drifted output and the sea level would ratchet up run after run.
Sea level belongs to the input. Both generation paths reconcile the model's land body back to your datum on every section run, so the model's coastal detail is kept while sea level stays yours. (keep_ocean_flat and coastline_refine are deprecated wire fields, mapped onto the two explicit coastline toggles below; sending them alongside those toggles is a 422.)
Climate is inherited untouched. The Köppen layer you imported or painted is carried straight through, so a re-generate never re-rolls your biomes.
The output is written as a signed 16-bit heightmap (<name>__loresat_signed.png) with a diffusion.signed decode contract recording the run's coarse geometry.
What it unlocks for colour#
The colour engine is physical. Every land tone is indexed off the heightfield: slope, concavity, ridge, routed catchment area and the climate layer. A hand-blocked heightmap carries almost none of that structure at kilometre scale, so an analytic render of it has very little to key on.
There is also a hard dependency. The satellite style needs the section's recorded pixel geometry, and pipeline.load_signed_elevation derives the ground pitch from the run's own coarse_cell_km and coarse_cells, never from the section's diagonal km_per_pixel. When that geometry is missing, the render adds a warning and falls back to the hypsometric style: elevation banding, with no palettes, rivers, snow, lakes or sea optical model. With no signed heightmap at all the render refuses outright and tells you to generate the section first.
The globe workspace names the order explicitly. Every region and tile moves through four stages: Rough terrain, Terrain detail, Analytic colour, Learned enhance. Terrain detail is this pass. Enhance section colour, the learned pass, is the last stage and needs an analytic colour render already on disk before it will run.
Before you run it#
Click Apply changes first. Generate conditions on the heightmap saved to disk, so brush strokes you have not applied are not in the conditioning.
Set your sea level before generating, not after. The Sea level slider in the Height brush group warns about this directly: moving it after a Generate reclassifies land and ocean the model authored.
Only one heavy job runs at a time. Generate is disabled while a render, an export, an Enhance section colour pass or a paint commit is in flight, and the server answers a clashing request with a 409 telling you to wait for the active job.
The models#
Coarse cell size is the scale contract. Get the model wrong and you get convincing terrain at the wrong feature scale.

| Tile | Engine id | Coarse cell | Pixels per cell | Native ground sample |
|---|---|---|---|---|
| 90 m | xandergos/terrain-diffusion-90m | 23 km | 256 | about 90 m/px |
| 30 m | xandergos/terrain-diffusion-30m | 7.7 km | 256 | about 30 m/px |
| Base-lite | loresat/base-lite | 23.5904 km | 20 | about 1,180 m/px |
The default is whatever the server reports as default_model, falling back to 90 m. The tile list is filtered to the models this installation is allowed to run, so a machine missing a model simply does not show it.
90 m and 30 m#
90 m is the continental recipe and the product default. 30 m is close enough to walk on and suits smaller, playable extents.
The dialog warns when 30 m is picked for a large section. Beyond 128 coarse cells on the long edge, the 30 m model's native output (cells x 256 px) no longer fits the 32,768 px combine ceiling, so continental extents want 90 m.
Base-lite#
Base-lite is Dayside's own continental model. It runs its own fixed recipe on a separate subprocess runtime, not the terrain diffusion sidecar, so the Detail presets, Precision, Elevation SNR, Feature scale, Rainfall conditioning, the Coastline toggles and Output resolution all disappear from the dialog and are ignored. Only Seed applies. Below a 3,000 km long edge the dialog says plainly that the 90 m and 30 m models will give you far more detail.
Base-lite needs its runtime configured through the LORESAT_BASE_LITE_* environment variables. When they are absent the tile is present but the dialog reports that base-lite is not configured on this machine and names the variables to set.
Choosing by extent#
Divide the section's long edge in km by the model's coarse cell to get the coarse grid, then multiply by 256 for the model's native output in pixels. A 4,000 km section at 90 m is about 174 cells, so about 44,500 px native, which the combine ceiling then caps.
Precision and output resolution#
Precision picks the inference dtype: Half · bf16 (the default, faster) or Full · fp32. The sidecar bakes the dtype into the loaded pipeline and reloads when you change it.
Output resolution has one toggle, Native output (uncapped), off by default. Left off, terrain inference follows the Output selection in the workspace header (Native, 2K, 4K, 8K, 16K, 32K), clamped to the 32,768 px combine ceiling. Turned on, the assembly runs at the model's own 256 px/cell with no ceiling at all.
Uncapped native is expensive in host RAM. When the estimate crosses 4 GB the dialog states roughly how much system memory the chunked assembly canvas will need while it combines chunks, and warns that the heightmap PNG will be similarly large.
The estimate line#
Under the toggle, the dialog states the terrain inference long edge, whether it was downscaled from native, the pixels per coarse cell and the resulting metres per pixel. Read the m/px figure rather than the pixel count: it is the honest statement of how fine the ground actually is.
Adherence and seed#
Detail presets#
The Detail section leads with three preset cards. One click sets the model, the SNR and the feature scale together.
Sketch is the default: the 90 m model at SNR 0.20, feature scale x1. It is the right card for a rough, hand-drawn map, because the model invents plausible detail below the cell scale where your sketch has nothing to say.
Faithful is for real or precise maps: the 30 m model at SNR 0.05, feature scale x1. It sticks closest to your terrain, and it is the slowest, at roughly five times the runtime.
Faithful, faster keeps the 90 m model at SNR 0.05 and raises the feature scale to x2. Measured against real ground it lands within a hair of Faithful at a fraction of the runtime.
The active card is derived from the dials, not stored. Move the model, the SNR or the feature scale off a preset's exact values and no card shows active; that is the implicit custom state, and nothing is lost.
Elevation SNR#
Elevation SNR is the adherence control, and its direction catches people out.
A lower value means stronger adherence. At 0.05 the model stays close to the terrain you drew. At 1.00 it departs freely and invents its own landform layout inside your coarse shape. Do not read the number as a detail dial, and do not read a higher value as "more detail". It is noise injected against your input.
Adherence also has a hard floor set by the model's coarse cell, and no SNR setting moves it. The model follows your map above about 6 cells (roughly 140 km at 90 m, 46 km at 30 m), sketches loosely between 1.5 and 6 cells, and below about 1.5 cells (roughly 35 km at 90 m, 12 km at 30 m) it invents everything, at realistic power but with no correlation to your input. The feature scale divides all of these figures. SNR tunes adherence only above that limit; the slider's own tip states the km figures for the model and feature scale you have dialed, and the feature scale control shows the effective cell size.
The slider covers 0.05 to 1.00 in steps of 0.05. The default is 0.20, the value the terrain-diffusion author recommends for imported heightmaps and the model's own CLI default. Internally snr_elev rides index 0 of a five-element vector, [snr_elev, 0.2, 1.0, snr_precip, 1.0].
Coastal fidelity. Ocean depth rides the same elevation channel at the same adherence, and the model's own ocean prior is weak, so shallows are the first thing it re-imagines. If a model-authored run must keep your authored shelves, straits and island layouts recognisable, set the slider to 0.05, which is what both Faithful presets do. Measured on a real continental section against the old 0.30 default, 0.05 roughly doubles shelf-bathymetry adherence and visibly preserves authored water-body shapes, at no cost in drowned land; the trade is tighter land too, so the model invents less landform variety everywhere.
Seed is a non-negative integer, default 0. The same seed over the same conditioning gives you identical terrain, so it is the control to move when you like the settings but not this particular arrangement of ranges.
Rainfall conditioning#
Rainfall conditioning is a two-way segment, Off or Use rainfall, default Use rainfall. On, the section's rainfall layer feeds the model's precipitation channel with an adherence of snr_precip 0.20. With no rainfall layer present the run degrades cleanly to elevation-only conditioning.
The physical scale comes from the rainfall layer's own recorded mm/year at white, set when you imported it. Only a layer with no recorded scale is read at the 3,000 mm/yr default, and that failure is silent: nothing looks broken, the model is simply conditioned at the wrong climate scale.
Hidden entirely for Base-lite.
Coastline options#
Model authors coastline is on by default and matches the Blender add-on recipe. The bathymetry guides the model-authored shore and generated ocean fades back to your authored sea floor by 600 m depth. Turn it off and the current land and sea boundary is preserved exactly.
Enhance coastline before generation runs the coastline refiner as a pre-pass, adding islands, bays and coastal detail before the model sees the section. It is off by default and disabled while Model authors coastline is on; turning that on force-clears this one. The two cannot be combined, and the API rejects the pair. Use it for terrain with no meaningful bathymetry, and leave it off when your sea floor is already authored.
Preserve land area appears only when Enhance coastline before generation is on and Model authors coastline is off. It sends preserve_area: true with island_density: 0 and bay_density: 0, so the refiner tidies the shoreline without adding or removing landmass.
The refiner's own knobs (dejag, coast_roughness, octaves, island_km, bay_km and the rest) are sent at their defaults from here. They are exposed where the coastline is authored, not in this dialog.
Control reference#
| Control | Engine key | Default | Range | What it does |
|---|---|---|---|---|
| Model tiles | model | xandergos/terrain-diffusion-90m (server may override) | the three ids above, filtered to what this machine allows | Sets the coarse cell size, and therefore the physical feature scale of everything generated. |
| Precision | dtype | bf16 | bf16, fp32 | Inference precision. bf16 is faster; the sidecar reloads its pipeline when this changes. |
| Native output (uncapped) | combine_res_cap | 32768 (toggle off) | 0 when on, 32768 when off | Drops the combine ceiling so the assembly runs at 256 px per coarse cell. |
| (workspace Output header) | output_resolution | auto | auto, or a long-edge px request up to combine_res_cap | Long edge the terrain is assembled at. Native and uncapped both send auto. |
| Elevation SNR | snr_elev | 0.20 | 0.05 to 1.00, step 0.05 (the API accepts any finite value) | Adherence to your input terrain above the model's scale floor; below about 1.5 cells the detail is invented at any setting. Lower is stronger adherence. |
| Seed | seed | 0 | integer, 0 and up | Same seed plus same conditioning gives identical terrain. |
| Rainfall conditioning | use_rainfall | true | on, off | Feeds the section's rainfall layer into the precipitation channel. |
| (fixed with rainfall on) | snr_precip | 0.20 | any finite value over the wire | Adherence for the precipitation channel. Only meaningful with use_rainfall. |
| (fixed) | precip_max_mm | 3000.0 mm/yr | any finite value over the wire | Fallback scale for a rainfall layer that recorded none of its own. |
| Model authors coastline | model_authors_coastline | true | on, off | On, the model draws the shoreline and ocean fades to the authored floor by 600 m. Off, the current land and sea split is preserved. |
| Enhance coastline before generation | coastline_enhance | false | on, off | Runs the coastline refiner as a pre-pass. Inert and disabled while Model authors coastline is on. |
| Preserve land area | coastline_params.preserve_area | false | on, off | Sends preserve_area: true, island_density: 0, bay_density: 0. Only visible when the refiner pre-pass is on and the model is not authoring the coast. |
| Revert to authored heightmap | (no key) | shown only when a snapshot exists | button | Restores the pre-generation authored heightmap. See below. |
Values the dialog fixes#
The dialog states these under Output resolution as add-on parity, and sends them on every non-base-lite run. They have no control.
| Control | Engine key | Default | Range | What it does |
|---|---|---|---|---|
| (none) | max_coarse_long | 64 | integer | Single-shot cap on the coarse-cell long edge. Over the cap a section auto-routes to chunked assembly rather than failing. |
| (none) | chunk_cells | 16 | integer | Chunked assembly only. Coarse cells per GPU read. Trades memory against batching, and never changes the terrain. |
| (none) | overlap_cells | 3 | integer | Chunked assembly only. Cross-fade margin between neighbouring reads, which turns the per-read DC step into a gradient. |
| (none) | water_level_m | 0 m | any finite value | Elevation counted as sea level for the land and sea split. |
| (none) | use_bathymetry | true | on, off | Composes ocean depth from the section's bathymetry crop. |
| (none) | deblock_lowfreq_reconcile | true | on, off | Chunked de-block: solves and blends per-chunk DC offsets, which is what removes square blocking. |
| (none) | skip_water_tiles | true | on, off | Skips chunks entirely below the coastal fade and fills them from the authored bathymetry. |
| (none) | keep_individual_tiles | true | on, off | Retains generated read regions as 16-bit PNGs with a tiles_index.json, for diagnosis and A/B replay. |
| (none) | target_peak_m | 0.0 | 0 for auto, else metres | 0 leaves the land peak to the model: the land is matched to your map block by block (mean height), and the summits are whatever the model drew above that. A positive value pins the land peak to it exactly. |
| (none) | relief_body_match | false | on, off | The local relief match. Opt-in, see below. |
Parameters with no control#
A few things are reachable over the API but deliberately have no slider.
Local relief match (relief_body_match, default false) lifts each block's land body so its relief distribution matches your input's, while holding the coastline and the block peak as fixed points, so it cannot move a shoreline or invent offshore land. It exists for the case where the model draws sharp peaks over flat ground: the block maximum already matches your input, so the flat between-peak body never rises. It is intentionally outside the parity recipe, the dialog sends false, and it is only honoured in the chunked assembly path. A single-shot run ignores it.
Ocean floor depth (ocean_floor_depth_m, default 6000.0 m) is the depth that bathymetry 1.0 maps to. Note that turning use_bathymetry off does not mean "land only" or "ocean at zero": it keeps a constant ocean floor at this value. The model was trained on real DEMs where the sea floor is negative metres, so an ocean at zero reads to it as flat coastal land and it invents coastal relief that is not there.
Land low-band swap (lowfreq_land_swap, default false) re-imposes your authored low frequency band on land. It is off by default as a deliberate divergence from the add-on: measured on real runs, the swap sank the model's healthy land body below sea level on low-lying worlds. It stays available as the rescue for a pathological global DC bias.
Single shot and chunked assembly#
A section whose coarse grid fits inside max_coarse_long (64 cells) generates in one pass. Anything larger auto-routes to chunked assembly, which generates in overlapping chunks and reassembles them. The engine calls this mode seamless, and you will see that word in the run's own warning. It takes noticeably longer than a single pass.
The two paths finish differently, and this is worth knowing when you compare results.
- Single shot: land reconcile, then ocean depth fade, then local peak match.
- Chunked: feather, then DC solve (de-block), then land reconcile, then depth fade, then local peak match.
Only the chunked path runs the optional local relief match.
Progress, time and cancelling#
The Generate button in the top bar becomes Generating N% and the modal closes as soon as the job is accepted. Progress moves through five reported stages:
| Stage | Reported at |
|---|---|
coastline | 1% |
conditioning | 4% |
queued | 8% |
generating | 15%, then creeps |
finalizing | 90% |
The generate stage is opaque. The sidecar reports only elapsed time, so the bar creeps asymptotically toward a ceiling of 85% with a 45 s time constant and never reports past it until the job actually finishes. A bar sitting near 80% is not stuck, it is waiting. If the server has not claimed a queued job within 180 s it concludes the runtime never came up and fails the job with the sidecar's own error.
There is no cancel control for a section Generate. The API carries a cancel route, but nothing in the interface calls it, and cancelling it would only stop the server waiting: the sidecar finishes the in-flight job either way. Plan on letting a section generate run.
The whole-globe pass is different. It appears as a card in the Job Dock with a working Cancel, and it can be resumed later from its checkpoint.
When the job finishes the editor reloads the section and renders the new terrain automatically.
Runtime and model readiness#
The dialog footer states the backend: Native NVIDIA CUDA ready, or a line saying there is no validated generation backend and that import remains available. Generate stays disabled until the runtime and the selected model are both ready.
When something is missing the dialog shows one message with one action. On a retail install the fix is to repair or reinstall Dayside, which restores the packaged runtime and model. On a development install you get Install and Download buttons and a staged progress line. Base-lite is judged only on its own runtime configuration and never on the sidecar gates.
Revert to authored heightmap#
The first time you Generate a section, Dayside copies the authored signed heightmap to an untouched sibling (<name>__authored_signed.png) before the generation overwrites it, and records enough provenance to restore it. Revert to authored heightmap in the dialog footer puts that file back and resets the section's provenance to the captured authored block.
Four things follow from how the snapshot works.
It is a one-shot slot. Later generates do not take a new one, so revert always returns you to the terrain as it was before the first Generate on this section, not to the previous generation.
The button appears only when a restorable snapshot exists and something has since overwritten the terrain. A section that has never been generated, or one generated before this feature shipped, has none, and the server says so.
Deterrace and the coastline apply that follows it also consume the slot, stamping a reason as they do. That is what keeps their own undo lit, because they preserve authored provenance and would otherwise leave the revert route dark.
Deterrace has its own separate Revert to previous heightmap, which is a different snapshot.
Whole globe terrain#
On the globe workspace, Enhance world opens a dialog with two stages that can be chained.
Enhance world terrain (default off) sweeps the whole planet with base-lite on the GPU and publishes an enhanced world heightmap as the world's active height layer. Skip deep ocean (default on, and only enabled when terrain is ticked) leaves windows below 300 m depth carrying their authored bathymetry instead of sampling them, which is most of an ocean world for a fraction of the runtime.
The globe colours in live while the pass runs. Tiles are published as the frontier advances, so the lit region genuinely is the rendered region. You can cancel at any time from the Job Dock and resume later from the checkpoint.
Colour globe (default on) is the second stage, and its label gains a note saying it starts when terrain finishes when both are ticked. The dialog carries a standing warning that this processes the entire world and can take many hours, and suggests running at least one focus-area section first to confirm you are happy with the look.
Two limits are worth stating. The globe equirect colour pass routes no flow, so it has no rivers and no lakes. And a whole-world diffusion pass can pay for detail that the retained tile crops then throw away, because crops persist at the tile canvas resolution; the server warns when fewer than 0.5 octaves of new detail survive.
Editing large sections at a working resolution#
A section whose native long edge is over 4,096 px prompts once on open with Edit at a working resolution?. Terrain-writing edits at full resolution are genuinely slow, and a single coastline edit on a very large section can take minutes.
The prompt offers 2K, 4K and 8K, filtered to those below your native long edge, with 4K marked recommended, plus Native to opt out. The choice is remembered per section on the server, so you are never asked twice.
Picking a working resolution downsamples the signed terrain to a proxy and points the section at it. The native master is not touched. Because the proxy carries the same coarse geometry, it reports a proportionally larger ground pitch, so every edit parameterised in metres stays correct at proxy resolution. Each terrain-writing edit records a resolution-independent operation in an edit journal.
While a proxy is active the banner under the top bar reads, for example, "Editing at 4K, native 8,192 x 8,192, 3 edits not yet baked".
Bake to native#
Bake to native replays your edits onto the full-resolution master. It is an explicit button and never fires automatically. It is disabled until you have drawn at least one edit, and it runs as a background job with progress in the banner.
Which bake runs depends on the machine. When the terrain diffusion runtime binds, you get the region bake. Without a bindable model or GPU it falls back to the structural bake, which replays the exact same native operation the slow path would have run. Editing works either way, and both report through the same job.
Region bake#
The region bake is the interesting one. Rather than re-diffusing the whole section, it takes the union of your lasso bounding boxes in normalised coordinates, grows that box by the coastline blend radius (so the bake does not leave a ring of un-diffused shelf around the regenerated core), maps it to a chunk window, and runs the model over that window only. The result is feather-blended back into the master, and the rest of the master stays byte for byte identical.
Height is blended locally. Colour is then recomputed for the whole section, so there are no colour seams, and the job only reports done once that recolour has finished.
One case cannot be localised: a from-heightmap refine reshapes the entire waterline, so its journal entry has no region and the bake diffuses everything.
Progress runs preparing, generating (n/total) chunks, compositing, publishing, then recolouring. The structural fallback reports replaying (n/total) instead.
Discard#
Discard throws the proxy edits away and restores the untouched master. Like Bake to native, it is disabled when there are no edits to act on.
After a bake, a large section that is back on native shows a resume banner offering Edit at 4K again, or Change… to pick a different working resolution.
Traps worth knowing#
Lower SNR means more adherence. It is the single most inverted-looking control in the dialog. And no SNR buys fidelity below the model's scale floor: under about 1.5 cells the detail is always the model's own invention.
A re-generate is not an iteration on the last result. Conditioning always comes from your authored terrain. If you want to build on a generated result, import it back as the section's terrain first.
Move sea level before you generate. Afterwards it reclassifies land and ocean the model authored.
Base-lite ignores nearly every control. Only Seed applies. If you set an SNR and a coastline policy and then switched to base-lite, none of it was sent.
The model's coarse cell is the feature scale. A 30 m run on a continental extent produces correct-looking terrain at the wrong scale, and the dialog will tell you when your extent crosses the 128-cell threshold.
Generate reads what is on disk. Apply your paint first.
Once the terrain is in, the next step is the analytic colour render, then optionally Enhance section colour for learned luminance detail on top of it.