CultLib/packages/cultmath
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Meta Vens ae3af9feb8 CultMath 0.4.1: Unity plugin DLL and pdb rebuilt on Windows at 0.4.1
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 04:48:31 +02:00
..
docs CultMath 0.4.0: state the true scope of the snoise tie change 2026-10-09 23:07:48 +02:00
native Move CultMath into the CultLib monorepo 2026-08-26 17:35:51 +02:00
scripts CultMath smoke: fail unless Unity exited 0 and this run wrote the passing results 2026-10-10 00:04:06 +02:00
shaders af_range finds a NaN endpoint by its bit pattern, which dxc's fast-math compare cannot fold [af-range-nan-guard-folded-by-dxc] 2026-10-04 11:09:25 +02:00
src CultMath 0.4.1: version, changelog (BoundedLeastSquares stopping fix, Validate), cultlib dependency pin 2026-10-11 04:31:21 +02:00
tests CultMath tests: pin the FreeViolated record of the real solves, column by column 2026-10-11 03:04:25 +02:00
tools CultMath tools: compile-glsl.ps1 -Phacelle concatenates CultMath.Phacelle.glsl after the library 2026-10-03 13:40:16 +02:00
unity/org.gamecult.cultmath CultMath 0.4.1: Unity plugin DLL and pdb rebuilt on Windows at 0.4.1 2026-10-11 04:48:31 +02:00
.gitignore Move CultMath into the CultLib monorepo 2026-08-26 17:35:51 +02:00
docs.meta Move CultMath into the CultLib monorepo 2026-08-26 17:35:51 +02:00
native.meta Move CultMath into the CultLib monorepo 2026-08-26 17:35:51 +02:00
README.md CultMath docs: magnitude-scaled float32 band; the frustum balls read no noise constant 2026-10-10 00:04:07 +02:00
README.md.meta Move CultMath into the CultLib monorepo 2026-08-26 17:35:51 +02:00
scripts.meta Move CultMath into the CultLib monorepo 2026-08-26 17:35:51 +02:00
shaders.meta Move CultMath into the CultLib monorepo 2026-08-26 17:35:51 +02:00
src.meta Move CultMath into the CultLib monorepo 2026-08-26 17:35:51 +02:00
tests.meta Move CultMath into the CultLib monorepo 2026-08-26 17:35:51 +02:00
THIRD-PARTY-NOTICES.md Document the snoise tie order in design.md and THIRD-PARTY-NOTICES 2026-10-04 03:26:10 +02:00
THIRD-PARTY-NOTICES.md.meta Move CultMath into the CultLib monorepo 2026-08-26 17:35:51 +02:00
tools.meta Move CultMath into the CultLib monorepo 2026-08-26 17:35:51 +02:00
unity.meta Move CultMath into the CultLib monorepo 2026-08-26 17:35:51 +02:00
web.meta Move CultMath into the CultLib monorepo 2026-08-26 17:35:51 +02:00

CultMath

CultMath is the project name. Its clean .NET package identity is GameCult.Math, owned and released from the CultLib monorepo.

Clean-room math shaped for people who think in HLSL.

CultMath provides lowercase vector types, shader-style intrinsics, and native hot-path kernels so math-heavy renderer code can move between C#, Rust, and HLSL without turning every line into a translation exercise. It is not a Unity.Mathematics clone. It is a small, Aquarium-born library built from public shader semantics.

Current Surface

  • float2, float3, float4
  • component-wise arithmetic
  • scalar-to-vector splats
  • every HLSL swizzle (xyzw and rgba, repeats readable, non-repeating masks writable) and every HLSL mixed constructor, generated by tools/generate-swizzles.ps1
  • conversions to and from System.Numerics
  • Random, a compact deterministic XORShift stream with scalar and vector draws
  • BatchMath SoA kernels over Span<float> / ReadOnlySpan<float> using System.Numerics.Vector<float> when available, including radial falloff acceleration and semi-implicit Euler integration
  • math intrinsics: radians, degrees, abs, floor, ceil, frac, 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 deterministic value-noise primitives
  • 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. It includes shaders/CultMath.Phacelle.hlsl (MPL-2.0) and shaders/CultMath.Interval.hlsl and shaders/CultMath.Affine.hlsl from the same directory, so ship all four.
  • interval arithmetic for culling empty space: iv_* functions over float2(lo, hi) (iv_add, iv_mul, iv_exp, iv_smoothstep, ...) and iv_snoise_ball/iv_fbm_ball, which bound snoise and fbm_grad over a ball, and iv_frustum_ball, the ball around a screen tile's rays over a depth segment, so one probe serves the whole tile (its radius carries its own float32 rounding bound). The arithmetic functions return an interval built to contain the function's value over their operand intervals, so a raymarch can skip a segment whose hi is below its cutoff; cultmath_iv_* in HLSL. The noise functions rest on empirical constants with a margin, not a proof: iv_snoise_ball(float3) on SNOISE_LIPSCHITZ (iv_fbm_ball through it), iv_snoise_ball(float2) on SNOISE2_LIPSCHITZ, and af_snoise on SNOISE_HESSIAN and SNOISE_LIPSCHITZ (af_fbm through it); the enclosure tests sample them. iv_frustum_ball and af_frustum_ball read no noise constant: the ball is geometry plus a rounding widening, and the noise call it feeds carries the constant. The bounds compose with a consumer's own analytic envelope (a height fog, a 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 (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 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.

Native Core

The canonical hot-path body lives in native/cultmath-core. It exports a C ABI for batch kernels such as cultmath_apollonian_voronoi_tones.

Runtime wrappers own syntax and integration. Rust owns optimized primitive kernel behavior and parity fixtures.

Example

using CultMath;

float3 normal = math.normalize(new float3(0.25f, 1.0f, -0.1f));
float rim = math.saturate(1.0f - math.dot(normal, new float3(0.0f, 0.0f, -1.0f)));
float glow = math.smoothstep(0.2f, 1.0f, rim);
float grain = math.value_noise_bicubic(math.float2(12.0f, 3.5f));
#include "CultMath.hlsl"

float3 normal = normalize(float3(0.25, 1.0, -0.1));
float rim = cultmath_saturate(1.0 - dot(normal, float3(0.0, 0.0, -1.0)));
float glow = cultmath_smoothstep(0.2, 1.0, rim);
float grain = cultmath_value_noise_bicubic(float2(12.0, 3.5));

Provenance

The small spline, damping, and pursuit helpers were promoted from Aetheria's local AetheriaMath surface. The value-noise family follows public shader literature from Inigo Quilez's noise and mini-spline articles, expressed in CultMath names with tests instead of copied project-local helper drift.

Build

dotnet build packages/cultmath/src/CultMath/CultMath.csproj
dotnet test packages/cultmath/tests/CultMath.Tests/CultMath.Tests.csproj
cargo test --manifest-path packages/cultmath/native/cultmath-core/Cargo.toml
cargo build --release --manifest-path packages/cultmath/native/cultmath-core/Cargo.toml
.\packages\cultmath\scripts\build-unity-package.ps1

Unity package

CultMath's Unity 2021.3 surface is the tracked precompiled package at packages/cultmath/unity/org.gamecult.cultmath. Unity consumes CultMath.dll and the numeric CultMath.hlsl; it does not compile the repository's current-language C# source tree and does not require a consumer csc.rsp workaround.

"org.gamecult.cultmath": "https://github.com/GameCult/CultLib.git?path=/packages/cultmath/unity/org.gamecult.cultmath"

The repository root is not a Unity package. Build the tracked package with packages/cultmath/scripts/build-unity-package.ps1; the script fresh-builds the netstandard2.1 assembly and rejects stale binaries, missing metadata, unexpected assemblies, or leaked C# source.

Before tagging cultmath-unity-v*, run the import and dispatch smoke on a Windows machine with a GPU, alone: packages/cultmath/scripts/unity-smoke/run-unity-smoke.ps1 -UnityExe <path to Unity.exe>. It builds a scratch project outside the repository that references the package by a file: path, dispatches a compute shader that includes CultMath.Interval.hlsl and CultMath.Affine.hlsl, requires a deliberately broken control shader to be rejected, and deletes the project afterwards.

Shader Tooling

CultMath keeps portable DXC outside git under packages/cultmath/.tools/:

.\packages\cultmath\tools\get-dxc.ps1
.\packages\cultmath\tools\get-spirv-cross.ps1
.\packages\cultmath\tools\compile-hlsl-spirv.ps1 `
  -ShaderPath E:\Projects\Odin\crates\muninn-move-tracker\shaders\MoveSphereCandidate.comp.hlsl `
  -OutputPath E:\Projects\Odin\crates\muninn-move-tracker\artifacts\shader\MoveSphereCandidate.comp.spv `
  -IncludePath E:\Projects\CultLib\packages\cultmath\shaders
.\packages\cultmath\tools\compile-spirv-metal.ps1 `
  -SpirvPath E:\Projects\Odin\crates\muninn-move-tracker\artifacts\shader\MoveSphereCandidate.comp.spv `
  -OutputPath E:\Projects\Odin\crates\muninn-move-tracker\artifacts\shader\MoveSphereCandidate.comp.metal

DXC emits Vulkan SPIR-V with -spirv. -TargetEnv vulkan1.2 is exposed by the script, but the current Windows DXC release compiled this shader successfully with DXC's default Vulkan target while rejecting the dotted target-env value. The SPIR-V script applies default Vulkan register shifts for cbuffers, textures, UAVs, and samplers so cross-compiled Metal buffers do not alias by resource class. SPIRV-Cross emits Metal Shading Language from SPIR-V on Windows; building an iPad-ready .metallib still belongs to Apple's Metal compiler on an Apple toolchain.

Doctrine

The goal is mechanical sympathy between CPU-side authoring, native kernels, and GPU-side shader math. If an intrinsic exists here, it should behave like the shader concept unless a runtime's numeric rules make that impossible. Weird deviations get tests and documentation, not folklore.

CultMath is still not a shader generator. Projects should include shaders/CultMath.hlsl directly or add that directory to their shader include path. If a shared operation needs CPU/GPU parity, put the primitive here and test it here before copying local math helpers into a renderer or daemon.