namespace IslaApocalypse.Tools { /// /// 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. /// public sealed class LookConfig { /// Short label, used in output filenames. public string Name = "atlas"; /// Which hypsometric palette. → . public ReliefPalette.Kind Palette = ReliefPalette.Kind.Atlas; /// /// Vertical exaggeration for the relief normal. ⚠ A LOOK DIAL, NOT A PHYSICAL CLAIM — the /// raw height units are not metres. See for the measured slope /// table this was chosen from. /// public float ZExaggeration = 75f; /// Compass degrees clockwise from north. 315° (NW) is the cartographic standard. public float LightAzimuth = 315f; /// Degrees above the horizon. 45° standard; lower = longer, more dramatic shadows. public float LightAltitude = 45f; /// /// 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. /// public float HillshadeStrength = 0.55f; /// /// 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. /// public float SeaHillshadeFactor = 0.35f; /// /// 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. /// public float HighlightGain = 0.5f; /// The colour boundary. NOT a water surface — no water is modelled (Phase 2). public float SeaLevel = 0.15f; /// /// 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 /// 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}"; } }