From 58546303647093be58dfd3d3f4f8d6e9e82db759 Mon Sep 17 00:00:00 2001 From: Meta Vens Date: Sun, 12 Jul 2026 19:20:15 +0100 Subject: [PATCH] Add stateless spherical erosion to Zyphos --- .../Shaders/D3D12ZyphosPlanet.hlsl | 28 ++++++++++++++++++- state/evidence.jsonl | 1 + state/map.yaml | 5 ++++ 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/src/Aquarium.Zyphos/Shaders/D3D12ZyphosPlanet.hlsl b/src/Aquarium.Zyphos/Shaders/D3D12ZyphosPlanet.hlsl index d75b6bb..debc2b9 100644 --- a/src/Aquarium.Zyphos/Shaders/D3D12ZyphosPlanet.hlsl +++ b/src/Aquarium.Zyphos/Shaders/D3D12ZyphosPlanet.hlsl @@ -3,6 +3,7 @@ static const int ZYPHOS_GEOMETRY_BRUSH_LIMIT = 4; #include "D3D12SdfCommon.hlsli" #include "D3D12SdfMath.hlsli" +#include "CultMath/CultMath.hlsl" float3 zyRotateZ(float3 p, float angle) { @@ -41,6 +42,30 @@ float zySphericalField(float3 dir) return 0.50 + plates + equatorialWarmth; } +float3 zySphericalFieldGradient(float3 dir) +{ + const float epsilon = 0.0015; + float dx = zySphericalField(normalize(dir + float3(epsilon, 0, 0))) - zySphericalField(normalize(dir - float3(epsilon, 0, 0))); + float dy = zySphericalField(normalize(dir + float3(0, epsilon, 0))) - zySphericalField(normalize(dir - float3(0, epsilon, 0))); + float dz = zySphericalField(normalize(dir + float3(0, 0, epsilon))) - zySphericalField(normalize(dir - float3(0, 0, epsilon))); + float3 gradient = float3(dx, dy, dz) / (2.0 * epsilon); + return gradient - dir * dot(gradient, dir); +} + +CultMathSphericalErosionSample zyErosion(float3 dir, float field) +{ + CultMathSphericalErosionParameters parameters; + parameters.frequency = 17.0; + parameters.amplitude = 0.012; + parameters.lacunarity = 2.03; + parameters.gain = 0.52; + parameters.slope_strength = 4.5; + parameters.detail = 1.35; + parameters.seed = 713.0; + parameters.octaves = 5; + return cultmath_spherical_erosion(dir, field, zySphericalFieldGradient(dir), parameters); +} + float zyHash21(float2 p) { p = frac(p * float2(123.34, 456.21)); @@ -227,6 +252,7 @@ float zyPebbleCluster(float3 dir) float zyTerrainOffset(float3 dir, SdfObject sdfObject) { float field = zySphericalField(dir); + CultMathSphericalErosionSample erosion = zyErosion(dir, field); float seaLevel = sdfObject.state.z; float land = smoothstep(seaLevel - 0.04, seaLevel + 0.08, field); float mountain = pow(saturate(field - seaLevel), 1.65); @@ -234,7 +260,7 @@ float zyTerrainOffset(float3 dir, SdfObject sdfObject) float authoredMaterial; float authoredGeometry = zyAuthoredBrushTerrainLimited(dir, ZYPHOS_GEOMETRY_BRUSH_LIMIT, authoredMaterial); float tileRelief = zyQuadtreeSdfRelief(dir) * land + zyLeafCluster(dir) * 0.018 + zyPebbleCluster(dir) * 0.010; - return (field - seaLevel) * 0.10 + mountain * 0.13 + polarCap * land + tileRelief + authoredGeometry * 0.52; + return (field - seaLevel) * 0.10 + mountain * 0.13 + polarCap * land + tileRelief + authoredGeometry * 0.52 + erosion.height_offset * land; } float sdfDistance(float3 p, int sdfIndex) diff --git a/state/evidence.jsonl b/state/evidence.jsonl index d968d26..f05df8d 100644 --- a/state/evidence.jsonl +++ b/state/evidence.jsonl @@ -332,3 +332,4 @@ {"ts":"2026-06-01T15:40:00+01:00","type":"implementation","status":"ok","note":"AquariumUiElement now carries an optional typed AquariumUiBinding descriptor for Verse-backed CultCache/CultMesh fields: document schema/id, field path, value kind, access, authority, and optional command id. Fensalir lowerings keep using local callbacks for native actuation; the binding is provenance/state authority metadata, not renderer-owned dashboard semantics.","files":["src/Aquarium.Engine.Contracts/Ui/AquariumUi.cs","state/map.yaml"]} {"ts":"2026-06-01T15:48:00+01:00","type":"verification","status":"ok","note":"Release build passed for Aquarium.Engine after adding AquariumUiBinding; Mimir Release builds and scene-editor smoke also passed against the updated contract.","files":["src/Aquarium.Engine.Contracts/Ui/AquariumUi.cs"],"source":"dotnet build src/Aquarium.Engine/Aquarium.Engine.csproj -c Release -p:UseSharedCompilation=false; dotnet run --project E:/Projects/Mimir/src/Mimir.BufferSmoke/Mimir.BufferSmoke.csproj -c Release -- --scene-editor-smoke"} {"ts":"2026-06-01T20:15:00+01:00","type":"implementation","status":"ok","note":"Render debug mode 21 is now an owner-layer overdraw view. Scene/evidence pixel shaders write a fifth additive R16_FLOAT overdraw target after discard/depth eligibility; presentation samples that target as a heat map. Coverage, step count, reservoir stats, and spatial-budget modes remain separate diagnostics instead of being relabeled as overdraw.","files":["src/Aquarium.Engine.Contracts/GraphicsSettings.cs","src/Aquarium.Engine/Render/D3D12Renderer.cs","src/Aquarium.Engine/Render/Shaders/D3D12Scene.hlsl","src/Aquarium.Engine/Render/Shaders/D3D12SdfCommon.hlsli","src/Aquarium.Engine/Render/Shaders/D3D12SdfProxy.hlsli","src/Aquarium.Engine/Render/Shaders/D3D12TemporalGaussian.hlsl","src/Aquarium.Engine/Render/Shaders/D3D12FractalSplatRender.hlsl","src/Aquarium.Engine/Render/Shaders/D3D12PointCloud.hlsl","src/Aquarium.Engine/Render/Shaders/D3D12TubeField.hlsl","src/Aquarium.Engine/Render/Shaders/D3D12Post.hlsl"],"source":"dotnet build Fensalir.sln; AQUARIUM_RENDER_DEBUG_MODE=21 .\\scripts\\dev-reload.ps1 -Headless -RetainSlots 4 -ClientProject src\\Aquarium.Fensalir\\Aquarium.Fensalir.csproj"} +{"timestamp":"2026-07-12T19:25:00+01:00","topic":"stateless-spherical-erosion","lesson":"Cube-sphere erosion must be a pure planet-space point function rather than six face-local filters or a repair pass. CultMath now owns matching C# and HLSL kernels keyed by unit direction, tangent base gradient, seed, and bounded octave parameters; Zyphos composes the result after its continental field, while cube faces remain lookup and scheduling charts.","files":["E:\\Projects\\CultMath\\src\\CultMath\\SphericalErosion.cs","E:\\Projects\\CultMath\\shaders\\CultMath.hlsl","src/Aquarium.Zyphos/Shaders/D3D12ZyphosPlanet.hlsl","state/map.yaml"],"source":"user requested a C# CPU implementation in CultMath matching the GPU code"} diff --git a/state/map.yaml b/state/map.yaml index 7762807..11b72ac 100644 --- a/state/map.yaml +++ b/state/map.yaml @@ -71,6 +71,11 @@ invariants: terrain should be a quadtree of brush-painted surface tiles, subdivided by projected footprint, curvature, brush/material detail, silhouettes, and temporal uncertainty before SDF probes emit detail-adaptive surface splats. + - Stateless planetary erosion is owned by CultMath's spherical point kernel. + It reads unit planet position, base height, tangent gradient, seed, and + bounded octave parameters; cube faces and tiles are scheduling charts only. + CultMath maintains matching C# and HLSL bodies, while clients choose terrain + parameters and composition policy. - The shared reservoir is a fractal domain reservoir, not a texel cache. Pixel rows are the current D3D12 execution projection of selected domain evidence. Area-domain contributors must carry selected subpixel or local