CultMath docs: the Sites section, struct consumers and the surface list

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
Meta Vens 2026-10-16 18:27:09 +02:00
commit 5a94abfef4
2 changed files with 32 additions and 2 deletions

View file

@ -28,8 +28,12 @@ shader semantics.
`min`, `max`, `clamp`, `saturate`, `lerp`, `step`, `smoothstep`, `dot`,
`cross`, `length`, `distance`, `normalize`, `reflect`, `csum`, `erf`,
`erfinv` (scalar only), exponential
`decay`/`damp`, intercept/segment helpers, Catmull-Rom, Bezier curves, and
`decay`/`damp`, intercept/segment helpers (`distance_to_segment` in 2D and 3D, with and without `out closest`), Catmull-Rom, Bezier curves, and
deterministic value-noise primitives
- Site cells: `power_cells` and `multiplicative_cells` return the two nearest sites of a point as `CultSiteCells`,
`soft_gabriel_gate` gates a pair of sites by the empty-disc margin. Each is a loop over the shader steps
`cultmath_power_score` / `cultmath_multiplicative_score`, `cultmath_site_cells_empty`, `cultmath_site_cells_insert`,
`cultmath_site_cells_border` and `cultmath_gabriel_margin`; a shader loops over its own buffer.
- `shaders/CultMath.hlsl`, a canonical HLSL mirror include for shader-side
parity. HLSL already owns `float2`, `float3`, and `float4`; the include
exposes `cultmath_*` functions for shared semantics HLSL does not provide.

View file

@ -138,7 +138,8 @@ fields is compared to its C# counterpart field by field, recursing into each
field's own components, down to bit-for-bit scalars, matching each leaf's
declaration path (field names, not just position) and declared type as well
as its value. `CultCellular` (`math.cs`, `cellular`), `CultPhasor`
(`math.Phacelle.cs`, `phacelle`) and `SpanNoise` (`math.Span.cs`, `span_fbm`) are its consumers. A struct return with a mismatched, reordered-by-name, or
(`math.Phacelle.cs`, `phacelle`), `SpanNoise` (`math.Span.cs`, `span_fbm`) and `CultSiteCells`
(`math.Sites.cs`, `site_cells_insert`) are its consumers. `CultSiteCells` is also a struct parameter (`site_cells_insert`, `site_cells_border`). A struct return with a mismatched, reordered-by-name, or
retyped field does not get a second comparison path or a shape of its own;
it fails the same walk that already handles a bare vector return.
@ -488,6 +489,31 @@ Known C# friction: under `using static CultMath.math;` the constructor
functions (`float3(...)`, `float3x3(...)`) hide the type names in member access,
so static members need a qualified type (`CultMath.float3x3.Euler(...)`).
## Sites
A site is `float4(position.xyz, weight)`; a 2D consumer uses z = 0. `math.Sites.cs` scores a query point
against a site two ways and keeps the two best:
- `power_score(p, site)`: value `|p - s|^2 - w^2`, gradient `2 (p - s)`. `F2 - F1` is affine in the query
point, so `site_cells_border`'s first-order distance is the exact distance to the power bisector.
- `multiplicative_score(p, site)`: value `|p - s| / w`, gradient `(p - s) / (|p - s| w)`, zero at `p = s`
(cellular's degenerate convention). Its borders are Apollonius circles, and the border distance is first order.
A span function is a C# loop over a per-site step that has a shader twin, because the HLSL mirror cannot take a
span or a buffer. `site_cells_empty()` starts the fold, `site_cells_insert(cells, score, index)` folds one score
in (strict `<` against F1, the old F1 moving to second, else strict `<` against F2, so an exact tie keeps the
earlier index first), and `site_cells_border(cells)` reads `float4(unit normal, distance)`, with `n = grad F2 -
grad F1` pointing toward the nearest site and `(0, 0, 0, 1.0e30)` when there is no second site. `power_cells` and
`multiplicative_cells` are that loop over a `ReadOnlySpan<float4>` and nothing else; a shader caller writes the
same loop over its own buffer. Every site of an explicit span is visited, so no window and no weight-ratio range
apply. `CultSiteCells` holds the two score fields and the two site indices (floats, -1 for none).
`gabriel_margin(a, b, other)` is `(|other - (a + b) / 2| - r) / r` with `r = |a - b| / 2`: zero on the diameter
circle, negative inside it, -1 when `a` and `b` coincide. `soft_gabriel_gate(sites, first, second, softness)`
is `smoothstep(-softness, softness, least margin over every other site)` on positions alone, 1 when no other site
exists; it is C# only. `distance_to_segment(point, start, end)` has out-free 2D and 3D forms beside the `out`
form, all over one `segment_closest` per dimension.
## Intervals
`math.Interval.cs` and `shaders/CultMath.Interval.hlsl` (included from