using Godot; namespace IslaApocalypse.Tools { /// /// PURE HILLSHADE (chat2/11) — a grayscale slope/aspect plate with no hypsometric tint, for /// reading low-amplitude surface detail (erosion's drainage is half a metre on average) that the /// palette-blended relief hides. Land shaded; sea a flat dark. ⚠ PRESENTATION ONLY — a look dial, /// never a claim about the world (→ Hillshade). /// public static class ShadeRenderer { public static Image Render(float[,] height, int mapSize, float sea, float zExaggeration, float azimuth, float altitude) { var (lx, ly, lz) = Hillshade.LightVector(azimuth, altitude); var img = Image.CreateEmpty(mapSize, mapSize, false, Image.Format.Rgb8); var seaColor = new Color(0.10f, 0.14f, 0.22f); for (int x = 0; x < mapSize; x++) for (int y = 0; y < mapSize; y++) { if (height[x, y] < sea) { img.SetPixel(x, y, seaColor); continue; } float s = Hillshade.At(height, mapSize, x, y, zExaggeration, lx, ly, lz); img.SetPixel(x, y, new Color(s, s, s)); } return img; } public static void SavePng(float[,] height, int mapSize, float sea, float zExaggeration, float azimuth, float altitude, string absolutePath) { Error err = Render(height, mapSize, sea, zExaggeration, azimuth, altitude).SavePng(absolutePath); if (err != Error.Ok) GD.PrintErr($"[ShadeRenderer] SavePng failed ({err}) for {absolutePath}"); } } }