Skip to content

About

Differentiable geometry library for Slang — SDFs, typed CSG combinators, raymarching, autodiff surface normals

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

20 Commits

Folders and files

Repository files navigation

geom.slang

A differentiable geometry library for Slang: 2D/3D signed distance fields, typed CSG combinators, raymarching, autodiff surface normals, quaternions, noise, color spaces, and PBR helpers — designed so call-site code reads like geometry, not like inline assembly.

import geom;

// Composition is a value; Slang monomorphises it into one inlined function.
let scene = smoothUnion3(
    translated3(Sphere(1.0), float3(1.0, 0.0, 0.0)),
    Box3D(float3(0.6)),
    0.2
);

let hit = scene.raymarch(ray);        // sphere trace + autodiff normal
let n   = scene.surfaceNormal(p);     // one backward-AD pass, not 6 SDF evals
let d   = (Circle(20.0) | Box2D(float2(15.0))).distance(p);   // operator CSG

Why this library

  • Autodiff-first. SDFs, CSG operators, transforms, noise, colour and BRDF math are [Differentiable], kinks included. A min in a union or an abs in a fold is non-smooth only on a measure-zero set, and Slang pushes a subgradient through it (at an exact tie it splits the gradient evenly between both operands). Lattice indices go through no_diff(floor(...)), which is exact because they are piecewise constant. What stays out is code whose output has no meaningful derivative, such as hexAxialRound and the degenerate-input fallbacks in safeNormalize or quatFromTo; each says so in its doc comment. Surface normals come from one backward-mode pass through the SDF instead of six central-difference evaluations.
  • Two API styles, one codegen. A functional layer (sdCircle, opSmoothUnion, …) and a typed-generic layer (Circle, SmoothUnion2<A, B>, operators |/&/-). Slang specialises the generics at compile time, so both styles emit the same machine code — pick per call site. One difference under autodiff: typed shapes are [NoDiffThis], so they differentiate with respect to the query point only. For gradients with respect to shape parameters (radius, offset, blend k), use the functional layer.
  • Batteries for procedural scenes. Hex-grid math (axial coords, cube rounding), path extrusion along polylines and arbitrary parametric curves (closest-point solved per pixel with bracketed Newton iterations; the closest-point parameter carries its implicit-function derivative, so autodiff normals stay correct for non-circular sections), Perlin/value/Worley noise with compile-time-unrolled FBM, Oklab, ACES, GGX, and a fast terrain erosion filter with analytically tracked slopes.

See geom/README.md for the full API overview.

Try it in 30 seconds

Every demo in playground/ has a single-file bundle in playground/dist/ with the library inlined. Paste one into the Slang playground and run — no install, no build.

Good starting points: csg_2d (typed CSG), raymarch_3d (lit 3D scene), helix (a user-defined parametric curve extruded into a solid — the library does the closest-point solve), terrain_3d (FBM heightfield, AD normals, Oklab altitude ramp, ACES), and advanced_erosion_terrain (the erosion filter end-to-end — a faithful port of Rune Skovbo Johansen's Shadertoy, with the filter's analytically tracked slopes driving the shading).

After editing library or demo sources, regenerate the bundles with scripts/playground-bundle.sh.

Using it in your project

Put the geom/ directory on your include path and import the module:

slangc your_shader.slang -I path/to/geom.slang/geom -target metal ...
import geom;

geom/geom.slang is the public umbrella module; implementation files live under geom/src/ and are __included into it, so callers see one stable module.

Compiler

The known-good compiler is Slang 2026.9.1 — the newest release that builds this library on all five targets (WGSL, GLSL, SPIR-V, HLSL, Metal).

ℹ️ Slang 2026.9.2 and 2026.10 break __bwd_diff of a member method (shader-slang/slang#11356), which is the natural way to write the library's autodiff normals — and it is what the online Slang playground runs. The library sidesteps the bug (the gradient default methods differentiate free-function relays instead of this.distance), so validation passes on 2026.7.1 / 2026.9.1 / 2026.9.2 / 2026.10 and the playground bundles load on current compilers. 2026.9.1 remains the most-tested release. If you extend the library: never apply __bwd_diff/__fwd_diff to a member method — route it through a free generic function.

A versioned install with a stable symlink makes the pin painless:

~/.local/slang/
├── 2026.9.1/            # known-good
└── current -> 2026.9.1  # put current/bin on PATH

Validation

scripts/validate.sh

Compiles the test shaders under geom/tests/ to WGSL, GLSL, SPIR-V, HLSL and Metal with slangc ($SLANGC if set, otherwise slangc on PATH) and validates the WGSL with naga (brew install naga-cli or cargo install naga-cli). geom/tests/compile_test.slang exercises every public symbol; geom/tests/robustness_test.slang covers degenerate inputs. CI runs the same script on every push.

Layout

path contents
geom/ the library — see geom/README.md
geom/tests/ compile + robustness test shaders
playground/ demo shaders for the Slang playground
playground/dist/ generated single-file bundles (library inlined)
scripts/ validation + bundling

License

Apache-2.0, with one exception: geom/src/erosion.slang is a port of Rune Skovbo Johansen's MPL-2.0 erosion filter and remains MPL-2.0 (MPL applies per file; see that file's header).

References

About

Differentiable geometry library for Slang — SDFs, typed CSG combinators, raymarching, autodiff surface normals

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages