Add stateless spherical erosion to Zyphos

This commit is contained in:
Meta Vens 2026-07-12 19:20:15 +01:00
commit 5854630364
3 changed files with 33 additions and 1 deletions

View file

@ -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)

View file

@ -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"}

View file

@ -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