Cut 2a-i fix batch 1, findings F1, F3, F4, F5, F6, F7 (Soul falsification of the first landing): - cellular now searches a provably exact 5x5x5 neighbourhood (radius 2), not 3x3x3: 3x3x3 missed the true F2 for 9 of 400,000 sampled points. The comment in math.cs proves 5x5x5 always contains the true F1 and F2 (both are always < sqrt(3), every excluded cell is always > 2). A cheap position-only lower-bound prune skips the pcg3d/jitter/distance work for cells that provably cannot beat the running F2, without changing any output bit (F6). - F2 = 0 now gets the same degenerate-gradient guard F1 = 0 already had, fixing a NaN that was reachable past |p| of about 2^23 (F3). - id now comes from pcg4d over the winning cell alone, never from the pcg3d hash that produced that cell's jitter, so id and jitter are no longer deterministic functions of each other (F4). - cellular_unit maps the top 24 bits instead of a plain divide-by-2^32, so the mapping is always inside [0, 1); the old formula rounded 0xFFFFFF80..0xFFFFFFFF up to exactly 1.0f (F7). - Central-difference tolerances tightened from 0.02 to 3e-4 (measured float noise at the committed eps is about 6e-5), and cellular's own gradient test now differentiates cellular's RETURNED .w values instead of a duplicate FindF1F2 search, so a mutant that corrupts only the returned gradient can't hide behind an independently-computed value (F1, F5). - The struct-mirror comparison in HlslSourceCompatibilityTests now checks field name and declared type in declaration order, not just position, so a reordered-and-relabelled mirror struct (H2) or a renamed/retyped one (H3) both fail the walk instead of surviving on values alone (F2). - FindF1F2 widened to a true independent 7x7x7 brute-force oracle; new tests pin production's exact agreement with it, the pruned search's bit-for-bit equivalence to an unpruned 5x5x5 reference, no NaN at 2^24, and id's correlation with jitter under 0.05. - Comment/doc fix: smin_grad is Quilez's quadratic-polynomial smin, not cubic. Both shaders/CultMath.hlsl and unity/.../Shaders/CultMath.hlsl stay byte-identical. Manually verified mutants M9 (grad1 x 1.01), M16 (grad2 x 1.01), and M18 (id from hash.y) all die against these tests; H2/H3 struct mutants die via the new comparator tests. Local dotnet test: 191/191 passing. FXC cs_5_0 compile of a scratch kernel using both cultmath_smin_grad and cultmath_cellular succeeds. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
26 lines
883 B
C#
26 lines
883 B
C#
namespace CultMath;
|
|
|
|
/// <summary>
|
|
/// The value-and-gradient result of <see cref="math.cellular(float3)"/> (invariant 8's one struct
|
|
/// return shape). Every field follows the same <c>float4(gradient.xyz, value.w)</c> layout as a
|
|
/// bare value-and-gradient return.
|
|
/// </summary>
|
|
public struct CultCellular
|
|
{
|
|
/// <summary>(∇F1, F1): the gradient and distance to the nearest feature point.</summary>
|
|
public float4 nearest;
|
|
|
|
/// <summary>(∇F2 - ∇F1, F2 - F1): for lineae along cell borders.</summary>
|
|
public float4 edge;
|
|
|
|
/// <summary>The nearest cell's pcg4d hash, mapped to [0, 1); independent of the pcg3d hash that
|
|
/// produced that cell's jitter.</summary>
|
|
public float id;
|
|
|
|
public CultCellular(float4 nearest, float4 edge, float id)
|
|
{
|
|
this.nearest = nearest;
|
|
this.edge = edge;
|
|
this.id = id;
|
|
}
|
|
}
|