Folds in the operator's rulings: Q1 cultmath-tapes, Q2 samples then resolution, Q3 the shader owns a dynamic ground and the CSS wash is sampled from its result. The nebula is flow-warped (two-phase flow map) with one flow texture owning motion for the warp, the TAA motion vectors, the hue and the stardust. Interval culling encloses the warp by enlarging the ball; interval-ops gains that test. New fourth cut site-stardust: stateless instanced particles plus an opacity-driven gather on the stardust layer, the web form of the raymarch-driven DoF. Budget re-checked: the full stack lands a mid-range phone at S = 4-6, not 8. Docs only. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
141 lines
11 KiB
JSON
141 lines
11 KiB
JSON
{
|
|
"campaign": "cultmath-tapes",
|
|
"cut": "glsl-lowering",
|
|
"revision": 1,
|
|
"title": "GLSL lowering: shaders/CultMath.glsl is generated from CultMath.hlsl by one enumerated textual transformation, pinned by a test, compiled by glslang, with a committed golden fixture for WebGL2 parity",
|
|
"repo": "GameCult/CultLib",
|
|
"branch": "hands/cultmath-glsl-lowering",
|
|
"base": "c49c76ee",
|
|
"depends_on": [],
|
|
"first": [
|
|
"Map: docs/cultmath-interval-ground-cut.md, sections 'Where the interval math lives' (route C) and 'The authority map'. Model: the HLSL -> C# mirror in tests/CultMath.Tests/HlslSourceCompatibilityTests.cs (wrapper at :348) and its complete transformation list in packages/cultmath/docs/design.md:92-134. The GLSL lowering follows the same discipline: a complete, enumerated list; anything outside it fails the test rather than being patched around.",
|
|
"Read how HlslSourceCompatibilityTests resolves #include \"CultMath.Phacelle.hlsl\" (CultMath.hlsl:506); the GLSL lowering inlines the included file at that line, because GLSL has no #include.",
|
|
"Target dialect: GLSL ES 3.00 (#version 300 es), WebGL2. No implicit int/uint -> float conversion; step(vec4, float) and max(vec4, float) differ (max(genType, float) exists, step(genType, float) does not); C-style casts do not exist; lerp/frac/saturate/rsqrt/asuint are mix/fract/clamp(x,0.0,1.0)/inversesqrt/floatBitsToUint; floatN/intN are vecN/ivecN; static const is const. Mixed-signedness shifts are allowed.",
|
|
"Where the lowered text does not compile, fix the HLSL into the common subset with a legal, bit-identical HLSL edit (e.g. CultMath.hlsl:114 and :200 step(h, 0.0) -> step(h, float4(0.0, 0.0, 0.0, 0.0)); :471-473 and :502 (float)((uint)hash.x >> 8) before the float multiply). The HLSL -> C# mirror test and the FXC/dxc compiles keep those edits honest. Never special-case the lowering for one function.",
|
|
"Casts need a balanced-paren scanner, not a regex: (int)((state >> 28) + 4) at CultMath.hlsl:396 is the case that breaks a regex.",
|
|
"Dropped, as the C# mirror drops them: include guards (replaced by CULTMATH_GLSL guards), and the Texture2D/SamplerState functions at CultMath.hlsl:535-573. The GLSL declares no precision; the host shader does (precision highp float; precision highp int; the pcg hashes need 32-bit int).",
|
|
"Regeneration: the pin test writes shaders/CultMath.glsl when the environment variable CULTMATH_WRITE_GLSL=1 is set, then asserts equality. No new project, no PowerShell copy of the transformation.",
|
|
"Golden fixture: tests export 256 seeded points per function family (snoise float3/float2, snoise_grad, fbm_grad 4 octaves, ridged_grad, cellular, pcg3d/pcg4d, iv_* if present on main by then) with outputs as float32 bit patterns in hex, to tests/CultMath.Tests/fixtures/glsl-parity.json. JSON is tolerated here: the consumer is a browser-pane WebGL2 readback, a xenos boundary. The site cut evaluates it.",
|
|
"glslang: tools/get-glslang.ps1 fetches a pinned glslangValidator release the way tools/get-dxc.ps1 does; tools/compile-glsl.ps1 compiles a #version 300 es fragment wrapper that includes shaders/CultMath.glsl and calls every public function once. Run on Starfire, one job, detached with a log, polled in the foreground.",
|
|
"Verification on Yggdrasil: dotnet test from packages/cultmath/tests/CultMath.Tests; Stryker --since:c49c76ee from a plain clone (not a linked worktree: Stryker resolves --since paths against the main checkout). Never run verification as a background shell task."
|
|
],
|
|
"deletes": [],
|
|
"keeps_moves": [
|
|
"Both tracked CultMath.hlsl copies (packages/cultmath/shaders and unity/org.gamecult.cultmath/Shaders) stay one blob; the common-subset edits land in both.",
|
|
"The C# mirror test, the FXC probe and dxc -T lib_6_3 -HV 2021 all still pass on the edited HLSL; the Unity package does not ship the GLSL file.",
|
|
"design.md's HLSL -> C# transformation list (92-134) is unchanged; the GLSL list is a new sibling section."
|
|
],
|
|
"adds": [
|
|
"tests/CultMath.Tests/GlslLowering.cs: the HLSL -> GLSL ES 3.00 transformation, one static function string -> string, with the list as named steps in order: inline includes; drop guards and texture functions; type names; static const; casts via the balanced scanner; intrinsic renames (lerp, frac, saturate, rsqrt, asuint/asfloat); float literal passthrough; guards CULTMATH_GLSL added; a provenance header line naming the source file and that the file is generated.",
|
|
"tests/CultMath.Tests/GlslMirrorTests.cs: CommittedGlslEqualsLowering (writes when CULTMATH_WRITE_GLSL=1, prints a unified diff on failure); NoHlslOnlyTokensSurvive (regex over the output for float[234]\\(|int[234]\\(|lerp\\(|frac\\(|saturate\\(|static const|\\((float|int|uint)\\)|Texture2D|SamplerState -> 0 matches); EveryPublicFunctionIsLowered (the set of cultmath_* function names in the HLSL minus the texture ones equals the set in the GLSL); GoldenFixtureMatchesCSharp (regenerates the fixture in memory from C# and asserts equality with the committed file).",
|
|
"shaders/CultMath.glsl: the committed generated artifact.",
|
|
"tests/CultMath.Tests/fixtures/glsl-parity.json: the golden fixture (seed, points, per-function expected bit patterns, tolerance class per function: exact for integer-hash paths, ulp-bounded for transcendental).",
|
|
"tools/get-glslang.ps1 and tools/compile-glsl.ps1, mirroring get-dxc.ps1 / compile-hlsl-spirv.ps1 in shape.",
|
|
"packages/cultmath/docs/design.md: a section 'GLSL Target: Source Transformations' after :134 with the complete list, the common-subset rule for HLSL, the regeneration command, and that the GLSL is a derived file never edited by hand.",
|
|
"packages/cultmath/README.md: one paragraph that CultMath.glsl exists, what dialect it is, and how a WebGL consumer includes it (string concatenation before its own #version-led source; declare highp)."
|
|
],
|
|
"file_changes": [
|
|
{
|
|
"location": { "path": "packages/cultmath/shaders/CultMath.hlsl", "line": 114 },
|
|
"change": "step(h, 0.0) -> step(h, float4(0.0, 0.0, 0.0, 0.0)); same at :200. Bit-identical in HLSL and C#."
|
|
},
|
|
{
|
|
"location": { "path": "packages/cultmath/shaders/CultMath.hlsl", "line": 470 },
|
|
"change": "jitter components and the id at :502: an explicit (float) cast around the shifted uint before the float multiply, so the lowered text has no uint*float."
|
|
},
|
|
{
|
|
"location": { "path": "packages/cultmath/shaders/CultMath.Phacelle.hlsl", "line": 1 },
|
|
"change": "whatever common-subset edits the glslang compile demands; each one bit-identical, each one listed in the cut report."
|
|
},
|
|
{
|
|
"location": { "path": "packages/cultmath/docs/design.md", "line": 134 },
|
|
"change": "new section: GLSL Target: Source Transformations."
|
|
}
|
|
],
|
|
"authority_map": {
|
|
"owner": "GlslLowering (tests/CultMath.Tests) owns the HLSL -> GLSL transformation; shaders/CultMath.glsl is its derived output, pinned by GlslMirrorTests. CultMath.hlsl stays the one hand-written shader source.",
|
|
"inputs": [
|
|
"shaders/CultMath.hlsl and shaders/CultMath.Phacelle.hlsl text",
|
|
"C# math for the golden fixture values"
|
|
],
|
|
"outputs": [
|
|
"shaders/CultMath.glsl (GLSL ES 3.00 library, every public cultmath_* function except texture samplers)",
|
|
"tests/CultMath.Tests/fixtures/glsl-parity.json"
|
|
],
|
|
"derived_state": [
|
|
"CultMath.glsl is derived; a hand edit fails CommittedGlslEqualsLowering",
|
|
"the fixture is derived from C#; a stale fixture fails GoldenFixtureMatchesCSharp"
|
|
],
|
|
"forbidden_writers": [
|
|
"no per-function special case in the lowering; a dialect gap is fixed in the HLSL in the common subset",
|
|
"no second transformation implementation (no PowerShell or JS copy of the rules)",
|
|
"no GLSL in the Unity package; no precision statement in the library file"
|
|
],
|
|
"shared_paths": [
|
|
"both tracked CultMath.hlsl copies receive the same edits; the existing one-blob rule covers them",
|
|
"the same dotnet test run pins the C# mirror, the GLSL pin and the fixture"
|
|
],
|
|
"deletion_line": "Nothing is deleted in CultLib. The liability bought is one generated file, one test file, one fixture and two tool scripts; what it retires is every future hand copy of CultMath noise in a GLSL consumer, starting with the site."
|
|
},
|
|
"verification": {
|
|
"builds": [
|
|
"Yggdrasil: dotnet test packages/cultmath/tests/CultMath.Tests green; paste counts",
|
|
"Yggdrasil: dotnet stryker --since:c49c76ee from a plain clone; triage every survivor by name",
|
|
"Starfire: tools/compile-glsl.ps1 exits 0 on the wrapper over shaders/CultMath.glsl; a negative-control wrapper with one lerp( call must fail (records that the compile check sees errors)",
|
|
"Starfire: FXC cs_5_0 and dxc -T lib_6_3 -HV 2021 still compile both HLSL copies after the common-subset edits"
|
|
],
|
|
"tests": [
|
|
{
|
|
"name": "GlslMirrorTests.CommittedGlslEqualsLowering",
|
|
"pins": "the committed GLSL is exactly the lowering of the committed HLSL; the regeneration path is the same code."
|
|
},
|
|
{
|
|
"name": "GlslMirrorTests.NoHlslOnlyTokensSurvive",
|
|
"pins": "the list is complete: no HLSL-only token survives in the output."
|
|
},
|
|
{
|
|
"name": "GlslMirrorTests.EveryPublicFunctionIsLowered",
|
|
"pins": "no function is silently dropped except the texture samplers."
|
|
},
|
|
{
|
|
"name": "GlslMirrorTests.GoldenFixtureMatchesCSharp",
|
|
"pins": "the fixture the site will read on WebGL2 is C#'s current truth."
|
|
},
|
|
{
|
|
"name": "HlslSourceCompatibilityTests.EveryMirrorFunctionMatchesCSharpMath (existing)",
|
|
"pins": "the common-subset edits changed no bit of any HLSL function."
|
|
}
|
|
],
|
|
"negative": [
|
|
{
|
|
"pattern": "lerp\\(|frac\\(|saturate\\(|float[234]\\(|int[234]\\(|static const|\\((float|int|uint)\\)|Texture2D|SamplerState|#include",
|
|
"scope": "packages/cultmath/shaders/CultMath.glsl: 0 matches."
|
|
},
|
|
{
|
|
"pattern": "precision (high|medium|low)p",
|
|
"scope": "packages/cultmath/shaders/CultMath.glsl: 0 matches (the host declares precision)."
|
|
},
|
|
{
|
|
"pattern": "CultMath\\.glsl",
|
|
"scope": "packages/cultmath/unity/**: 0 matches; the Unity package does not ship the GLSL."
|
|
},
|
|
{
|
|
"pattern": "git diff c49c76ee..HEAD -- packages/cultmath/shaders/CultMath.hlsl | grep '^[-+]' | grep -v '^[-+][-+]'",
|
|
"scope": "every changed HLSL line is listed in the cut report with the reason (dialect gap it closes); none changes a value, proven by the mirror test and the existing goldens."
|
|
}
|
|
],
|
|
"operator": []
|
|
},
|
|
"estimate": {
|
|
"lines_added": 1100,
|
|
"lines_removed": 8,
|
|
"dependencies_added": [],
|
|
"dependencies_removed": [],
|
|
"formats_added": ["GLSL ES 3.00 library file (generated)", "glsl-parity.json fixture"],
|
|
"formats_removed": [],
|
|
"targets_added": [],
|
|
"targets_removed": []
|
|
},
|
|
"rulings": [],
|
|
"questions": []
|
|
}
|