Presentation only. No generation file is touched — Topography, TerrainNoise, IslandFalloff, Pass1Result, TerrainGenConfig and GenerationScale are all unchanged. Batch naming, fixed in code. The prefix is the AUTHORING TASK number, not a running counter: 04_review means "the batch task 04 authored", not "the fifth batch". It had already drifted — tasks 02 and 03 produced 00_smoke through 05_trophy_10240 across two tasks, so no folder name said which task made what. Now the task number is an explicit argument to ToolingPaths.BatchRoot(taskNumber, descriptor), which composes the prefix itself and REFUSES a descriptor that carries its own. All three tools take it as ISLA_TASK. Verified: ISLA_BATCH=05_foo is refused with a stated reason and exit 2, and creates no folder. Also fixed: an exception out of _Ready does not stop Godot — it logs and the process sits there with no main loop, so a misconfigured run HUNG rather than failing. A hang looks like slow work, which is worse than a crash. The batch tools now catch, print what was refused, and exit non-zero. Grayscale mode: normalize a field to its own [min,max]. This is the one place per-image normalization is correct — everywhere else anchors are fixed so images compare, but here the point is to see one field at full contrast. The range is printed and indexed so a shade reads back to a height. You cannot judge noise through a palette: a ramp bends the distribution, a hillshade adds shape the data does not have. The wide Costa-Rica palette, and the reframing the developer asked for: the pretty map is the WIDE GRADIENT RENDERED FLAT, and relief is no longer the hero. On raw pass-1 noise a hillshade has nothing coherent to shade, so it renders fine fractal bumpiness as fuzz that actively hides the elevation the colour is showing. Strong hillshade is retained as diagnostic_relief and labelled a dev view — its bumpiness is exaggerated slope, not extra terrain. Subtle relief is kept for comparison, with the honest note that it still fuzzes until Phase 2 carves coherent landforms. Legend: a colour bar with ticks drawn from the palette's own ramp, so it cannot drift from the map beside it. Ticks are RELATIVE height and the image says NOT METRES — the conversion is Phase 2's, and labelling it "m" would invent a fact in the artefact a reader most trusts. Text comes from a 5x7 bitmap font written for this, specifically so a legend does not drag in the SubViewport capture path.
124 lines
5.5 KiB
C#
124 lines
5.5 KiB
C#
namespace IslaApocalypse.Tools
|
||
{
|
||
/// <summary>
|
||
/// The presentation dials — everything about how a heightmap is SHOWN, and nothing about how it
|
||
/// is MADE. → `Design - Rendering - Roughness Is Presentation.md`.
|
||
///
|
||
/// ⚠ Config-gated for the same reason every shaping change is: a look decision should be an A/B
|
||
/// pair, not a memory of last week's render, and a rejected look should cost a flipped default
|
||
/// rather than a reverted commit. → `Design - Tooling - Iteration and Batching.md`.
|
||
///
|
||
/// ⚠ Kept DELIBERATELY SMALL. This is a taste gate, and iteration fatigue on a subjective gate
|
||
/// is a real failure mode — a handful of variants the eye can actually judge beats a wall of
|
||
/// near-duplicates. Three named looks, chosen so each pair isolates one question.
|
||
/// </summary>
|
||
public sealed class LookConfig
|
||
{
|
||
/// <summary>Short label, used in output filenames.</summary>
|
||
public string Name = "atlas";
|
||
|
||
/// <summary>Which hypsometric palette. → <see cref="ReliefPalette.Kind"/>.</summary>
|
||
public ReliefPalette.Kind Palette = ReliefPalette.Kind.Atlas;
|
||
|
||
/// <summary>
|
||
/// Vertical exaggeration for the relief normal. ⚠ A LOOK DIAL, NOT A PHYSICAL CLAIM — the
|
||
/// raw height units are not metres. See <see cref="Hillshade"/> for the measured slope
|
||
/// table this was chosen from.
|
||
/// </summary>
|
||
public float ZExaggeration = 75f;
|
||
|
||
/// <summary>Compass degrees clockwise from north. 315° (NW) is the cartographic standard.</summary>
|
||
public float LightAzimuth = 315f;
|
||
|
||
/// <summary>Degrees above the horizon. 45° standard; lower = longer, more dramatic shadows.</summary>
|
||
public float LightAltitude = 45f;
|
||
|
||
/// <summary>
|
||
/// How much the relief moves the tint. 0 = flat hypsometric tint, no shading at all;
|
||
/// 1 = full relief. Above ~0.85 the tint starts washing out and the map reads as a
|
||
/// greyscale DEM wearing colour.
|
||
/// </summary>
|
||
public float HillshadeStrength = 0.55f;
|
||
|
||
/// <summary>
|
||
/// Relief multiplier BELOW sea level.
|
||
///
|
||
/// ⚠ Deliberately much weaker than on land, and the reason is the deferral: the seabed is
|
||
/// RAW — no coast shelf, no islets, both Phase-2 items — so it is steep and noisy in a way
|
||
/// the finished terrain will not be. Shading it at full strength drags the eye to the one
|
||
/// part of the map that is knowingly unfinished. Cartographic bathymetry is conventionally
|
||
/// shown flat or lightly shaded anyway, so the convention and the deferral agree.
|
||
/// </summary>
|
||
public float SeaHillshadeFactor = 0.35f;
|
||
|
||
/// <summary>
|
||
/// How much of the lit side is allowed to lift toward white. Highlights SCREEN rather than
|
||
/// multiply, so sunlit slopes brighten without blowing out to paper.
|
||
/// </summary>
|
||
public float HighlightGain = 0.5f;
|
||
|
||
/// <summary>The colour boundary. NOT a water surface — no water is modelled (Phase 2).</summary>
|
||
public float SeaLevel = 0.15f;
|
||
|
||
/// <summary>
|
||
/// The three looks offered to the taste gate. Each pair isolates one question:
|
||
/// gradient_flat ⭐ the hero — wide colour, NO relief
|
||
/// subtle_relief the same gradient with gentle relief, for comparison
|
||
/// diagnostic_relief ⚠ a DEV VIEW for spotting artifacts. Never the pretty map.
|
||
/// atlas / dusk the task-03 plates, kept reachable
|
||
/// </summary>
|
||
public static LookConfig[] Variants() => new[]
|
||
{
|
||
// ⭐ THE HERO. A wide, vivid gradient rendered FLAT — no relief at all.
|
||
//
|
||
// The developer's reference maps get their look from WIDE COLOUR + subtle relief +
|
||
// COHERENT TERRAIN. We have the first; the third is Phase 2's curve and erosion. On raw
|
||
// pre-Phase-2 noise a hillshade has nothing coherent to shade, so it renders the fine
|
||
// fractal bumpiness as visual fuzz and actively HIDES the elevation the colour is
|
||
// showing. So the pretty map leads with colour and no relief, and gets its shape from
|
||
// relief later, once there is shape worth lighting.
|
||
new LookConfig
|
||
{
|
||
Name = "gradient_flat", Palette = ReliefPalette.Kind.CostaRica,
|
||
HillshadeStrength = 0f,
|
||
},
|
||
|
||
// Tasteful relief, for comparison. ⚠ Still fuzzes on raw noise — that is the terrain,
|
||
// not the setting. Comes into its own after Phase 2 carves coherent landforms.
|
||
new LookConfig
|
||
{
|
||
Name = "subtle_relief", Palette = ReliefPalette.Kind.CostaRica,
|
||
ZExaggeration = 18f, LightAzimuth = 315f, LightAltitude = 45f,
|
||
HillshadeStrength = 0.30f,
|
||
},
|
||
|
||
// ⚠⚠ A DIAGNOSTIC, NOT A PRETTY MAP. Strong exaggeration makes slope artifacts jump
|
||
// out — a centre-line crease, a stair-step, a seam. Its bumpiness is EXAGGERATED SLOPE,
|
||
// not extra terrain. Never present this as the deliverable.
|
||
new LookConfig
|
||
{
|
||
Name = "diagnostic_relief", Palette = ReliefPalette.Kind.CostaRica,
|
||
ZExaggeration = 100f, LightAzimuth = 315f, LightAltitude = 45f,
|
||
HillshadeStrength = 0.80f,
|
||
},
|
||
|
||
// The task-03 atlas plates, kept so that look is still reachable for comparison.
|
||
new LookConfig
|
||
{
|
||
Name = "atlas", Palette = ReliefPalette.Kind.Atlas,
|
||
ZExaggeration = 75f, LightAzimuth = 315f, LightAltitude = 45f,
|
||
HillshadeStrength = 0.55f,
|
||
},
|
||
new LookConfig
|
||
{
|
||
Name = "dusk", Palette = ReliefPalette.Kind.Dusk,
|
||
ZExaggeration = 100f, LightAzimuth = 300f, LightAltitude = 35f,
|
||
HillshadeStrength = 0.70f,
|
||
},
|
||
};
|
||
|
||
public override string ToString() =>
|
||
$"{Name}: palette={Palette} zex={ZExaggeration:F0} light={LightAzimuth:F0}°/{LightAltitude:F0}° " +
|
||
$"strength={HillshadeStrength:F2} sea×{SeaHillshadeFactor:F2}";
|
||
}
|
||
}
|