CultMath 0.4.0: state the true scope of the snoise tie change

The Breaking entry now names the whole tie set (inputs whose y-x and z-x are
whole numbers, every integer point included, change by up to 0.776), with
examples and a consumer warning; design.md and the NoiseGradTests comment drop
the narrower origin-and-(t,t,t) wording. Docs and test comment only; builds.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Meta Vens 2026-10-09 23:07:48 +02:00
commit 7bd34a96ce
3 changed files with 24 additions and 12 deletions

View file

@ -371,9 +371,11 @@ together, laid out as `float4(gradient.xyz, value.w)`, with no value-only twin
pins the continuity. Ties in the offset `x0` resolve in Gustavson's
`simplexnoise1234` order (x over y, y over z, x over z), a total order, so the
four corners are always a simplex. Upstream's `step` compares are cyclic: where
the three components are equal, which includes the origin and every
`(t, t, t)`, the corners repeat the origin vertex and the value jumps by about
0.77 near the origin and up to 1.56 at magnitudes of 64 and above. `NoiseGradTests.SnoiseIsContinuousOnTheSimplexDiagonal` pins the order.
the three components are equal, which is every input whose differences `y - x`
and `z - x` are whole numbers (every integer point, the origin and every
`(t, t, t)` among them), the corners repeat the origin vertex and the value
jumps by about 0.77 near the origin and up to 1.56 at magnitudes of 64 and
above. `SnoiseTieScopeTests` pins the set against the 0.3.0 values. `NoiseGradTests.SnoiseIsContinuousOnTheSimplexDiagonal` pins the order.
- `snoise_grad(float3 p)` carries `snoise(float3)` to value-and-gradient form,
following the differentiation in webgl-noise `src/noise3Dgrad.glsl` (Ashima
Arts / Ian McEwan, MIT), which uses the same radius, permutation and scale as

View file

@ -192,8 +192,9 @@ public sealed class NoiseGradTests
// The simplex diagonals are where x0's three components compare equal. The tie rule must be a total
// order there (math.snoise): with a cyclic or all-strict compare the four corners stop being a
// simplex and the value jumps on the line (t, t, t), lattice diagonals included: about 0.77 near the
// origin, up to 1.56 at magnitudes of 64 and above.
// simplex and the value jumps wherever x0 has three equal components (inputs whose differences y - x and
// z - x are whole numbers, the line (t, t, t) among them): about 0.77 near the origin, up to 1.56 at
// magnitudes of 64 and above. SnoiseTieScopeTests pins the set against the 0.3.0 values.
[Fact]
public void SnoiseIsContinuousOnTheSimplexDiagonal()
{

View file

@ -12,13 +12,22 @@ backfilled here; see `docs/semver-policy.md` for why.
- `math.snoise(float3)` and `math.snoise_grad`, and their HLSL mirrors in
`Shaders/CultMath.hlsl`, now resolve ties among the components of the cell
offset in a fixed order: x over y, y over z, x over z. The cyclic rule they
used before made the origin and every point on the `(t, t, t)` diagonal read a
different function from the points beside it. Values change at the origin and
on the `(t, t, t)` diagonal and nowhere else; off that tie set the results are
bit-identical to 0.3.0. `snoise` is now continuous across the diagonal to
within 1e-4 over two ulps either side (`NoiseGradTests`,
`SnoiseIsContinuousOnTheSimplexDiagonal`). Content seeded from `snoise` at
those points changes; regenerate it when you take this version.
used before read a different function wherever the three components of the
cell offset are equal. That is every input whose coordinate differences
`y - x` and `z - x` are whole numbers: every integer point (the origin
included), and the whole `(1, 1, 1)` line through each of them (`(t, t, t)`
among them). On that set values change by up to 0.776; for example
`snoise(0, 0, 0)` was -0.4358730 and is 0, `snoise(5, 0, 0)` was 0.7076616 and
is 0.671713, and `snoise(1, 2, 3)` was 0.22423841 and is 0. Float32 rounding
decides whether a given input ties, and an input that ties may still keep its
value; measured over random integer points, about 97% change. Off that set
the results are bit-identical to 0.3.0
(`SnoiseTieScopeTests`, goldens computed by the 0.3.0 DLL). `snoise` is now
continuous across the diagonals to within 1e-4 over two ulps either side
(`NoiseGradTests`, `SnoiseIsContinuousOnTheSimplexDiagonal`). Anything keyed
on integer lattice coordinates (voxel or tile seeds, cell centres, generated
content sampled on a whole-number grid) changes; regenerate it when you take
this version.
### Added