CultMath design.md and README: the two GLSL files, the concatenation order, the fixture's platform tolerance
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
8b970cbebf
commit
6d0a0c147d
2 changed files with 42 additions and 18 deletions
|
|
@ -47,12 +47,15 @@ shader semantics.
|
|||
carved sphere): its interval over the segment proves empty space in one probe,
|
||||
and the noise ball is consulted only near the surface. See `docs/design.md`,
|
||||
"Intervals".
|
||||
- `shaders/CultMath.glsl`, the same `cultmath_*` library in GLSL ES 3.00 for
|
||||
WebGL2, generated from `CultMath.hlsl` (never edited by hand). GLSL has no
|
||||
`#include`: a WebGL consumer concatenates the file's text after its own
|
||||
- `shaders/CultMath.glsl` (MIT), the same `cultmath_*` library in GLSL ES 3.00
|
||||
for WebGL2, generated from `CultMath.hlsl` (never edited by hand), and
|
||||
`shaders/CultMath.Phacelle.glsl` (MPL-2.0), generated from
|
||||
`CultMath.Phacelle.hlsl`, which holds `cultmath_phacelle` alone. GLSL has no
|
||||
`#include`: a WebGL consumer concatenates `CultMath.glsl` after its own
|
||||
`#version 300 es` line and `precision highp float; precision highp int;`
|
||||
(the library declares no precision, and its hashes need 32-bit integers),
|
||||
then appends its own shader source.
|
||||
then `CultMath.Phacelle.glsl` only if it calls `cultmath_phacelle`, then its
|
||||
own shader source.
|
||||
- `Voronoi.SampleTones`, a C# batch surface that calls the Rust
|
||||
`cultmath-core` native kernel when `cultmath_core` is available and falls back
|
||||
to the managed parity path otherwise.
|
||||
|
|
|
|||
|
|
@ -136,20 +136,28 @@ it fails the same walk that already handles a bare vector return.
|
|||
### GLSL Target: Source Transformations
|
||||
|
||||
`shaders/CultMath.glsl` is a GLSL ES 3.00 (WebGL2) library generated from
|
||||
`shaders/CultMath.hlsl` by `GlslLowering` (in the test project). It is a derived
|
||||
file: never edit it by hand. Regenerate it, and the golden fixture
|
||||
`shaders/CultMath.hlsl` by `GlslLowering` (in the test project), and
|
||||
`shaders/CultMath.Phacelle.glsl` is generated beside it from
|
||||
`shaders/CultMath.Phacelle.hlsl`. Both are derived files: never edit them by
|
||||
hand. Regenerate them, and the golden fixture
|
||||
`tests/CultMath.Tests/fixtures/glsl-parity.json`, with:
|
||||
|
||||
```powershell
|
||||
$env:CULTMATH_WRITE_GLSL = "1"; dotnet test packages/cultmath/tests/CultMath.Tests --filter GlslMirrorTests
|
||||
```
|
||||
|
||||
`GlslMirrorTests.CommittedGlslEqualsLowering` fails on any difference between the
|
||||
committed file and the lowering of the committed HLSL. These transformations,
|
||||
in order, are the complete list:
|
||||
`GlslMirrorTests.CommittedGlslEqualsLowering` fails on any difference between
|
||||
either committed file and the lowering of the committed HLSL. These
|
||||
transformations, in order, are the complete list:
|
||||
|
||||
1. Each `#include "name"` is replaced in place by the included file, by the
|
||||
same resolver the C# mirror uses; GLSL has no `#include`.
|
||||
same resolver the C# mirror uses; GLSL has no `#include`. The exception is
|
||||
an include under a file-level licence of its own, listed in one table,
|
||||
`GlslLowering.SeparateFiles`: its line is dropped and the file is lowered on
|
||||
its own, by the same steps, into its own output. The table has one entry,
|
||||
`CultMath.Phacelle.hlsl` to `CultMath.Phacelle.glsl`, because Phacelle is
|
||||
MPL-2.0 and MPL-2.0 is file-level: kept separate, it leaves
|
||||
`CultMath.glsl` MIT. Nothing else in the lowering is keyed by name.
|
||||
2. Include guards are dropped, and so are the functions taking
|
||||
`Texture2D`/`SamplerState`; the host shader samples its own textures.
|
||||
3. Type names: `floatN`, `intN`, `uintN` and `boolN` become `vecN`, `ivecN`,
|
||||
|
|
@ -162,8 +170,11 @@ in order, are the complete list:
|
|||
`inversesqrt`, `asuint` to `floatBitsToUint`, `asfloat` to
|
||||
`uintBitsToFloat`, and `saturate(x)` becomes `clamp(x, 0.0, 1.0)`.
|
||||
7. Float literals pass through unchanged.
|
||||
8. The library is wrapped in a `CULTMATH_GLSL` guard.
|
||||
9. The first line names the file as generated and says how to regenerate it.
|
||||
8. Each output is wrapped in a guard named for its file: `CULTMATH_GLSL`,
|
||||
`CULTMATH_PHACELLE_GLSL`.
|
||||
9. The first line names the file as generated, its sources and its licence,
|
||||
and says how to regenerate it; `CultMath.glsl`'s also says which
|
||||
functions live in the separate file.
|
||||
|
||||
GLSL ES 3.00 is stricter than HLSL: no implicit conversions between int, uint
|
||||
and float, no C-style casts, and no `step(genType, float)` overload. Those gaps
|
||||
|
|
@ -180,16 +191,26 @@ The library declares no precision. The host shader does, and it must be
|
|||
integers. `tools/compile-glsl.ps1` writes such a wrapper (its own `#version
|
||||
300 es` line, the precision, the library by string concatenation, and one call
|
||||
of every public function) and compiles it with glslang, which
|
||||
`tools/get-glslang.ps1` fetches pinned. The Unity package does not ship the
|
||||
GLSL file.
|
||||
`tools/get-glslang.ps1` fetches pinned. It runs twice: over `CultMath.glsl`
|
||||
alone, and with `-Phacelle` over `CultMath.glsl` followed by
|
||||
`CultMath.Phacelle.glsl`, the order a consumer that calls `cultmath_phacelle`
|
||||
concatenates them in. Two negative controls must fail: `-Body` with an HLSL
|
||||
token (`float x = lerp(0.0, 1.0, 0.5);`), and `-Body` calling
|
||||
`cultmath_phacelle` without `-Phacelle`, which proves the MIT file does not
|
||||
carry it. The Unity package ships neither GLSL file.
|
||||
|
||||
Parity runs in two legs, each with one owner: HLSL against C# by the mirror
|
||||
test, bit for bit; GLSL against C# by the golden fixture, which records 256
|
||||
seeded cases per function family as float32 bit patterns, evaluated by the
|
||||
consumer on WebGL2 and read back. Integer-only families (`pcg3d`, `pcg4d`) must
|
||||
match exactly; float families are ulp-bounded, the bound measured on the device.
|
||||
`iv_exp` is not in the fixture, because its C# bits come from the platform's
|
||||
`exp`.
|
||||
consumer on WebGL2 and read back. The families `pcg3d`, `pcg4d` and
|
||||
`iv_frustum_ball` are marked exact; the other float families are ulp-bounded,
|
||||
the bound measured on the device. `iv_exp` is in the fixture so the site can
|
||||
measure WebGL2's `exp`, but its C# bits come from the platform's `exp` and
|
||||
differ by OS: its tolerance is "ulp-bounded, platform exp", its entry names the
|
||||
platform that generated it, and `GoldenFixtureMatchesCSharp` compares it case
|
||||
by case within one ulp of the running platform, printing the largest distance.
|
||||
Every other family is compared as text. Every fixture family is in
|
||||
`CultMath.glsl`, so the parity run needs no `CultMath.Phacelle.glsl`.
|
||||
|
||||
## Invariant 8: Value-and-Gradient Primitives
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue