Compiler2 min read

SDF Module

Signed-distance primitives, composition helpers, debug masks, and raymarching helpers.

Reading Time
2 min
Word Count
222
Sections
10
Try It Live

Turn the guide into code

Take the key idea from this page into the playground and validate it in a real shader instead of leaving it as theory.

Open Playground

Signed-distance primitives, composition helpers, debug masks, and raymarching helpers.

Import

bwsl
import SDF

This module imports: Math.

Constants

None.

Structs

Ray

bwsl
struct Ray {
float3 origin;
float3 direction;
};

RaymarchResult

bwsl
struct RaymarchResult {
bool hit;
int steps;
float distance;
float3 position;
float surfaceDistance;
};

Enums

SDFShape

bwsl
enum SDFShape {
Sphere(float radius),
Box(float3 halfExtents),
RoundBox(float3 halfExtents, float radius),
Torus(float majorRadius, float minorRadius),
Capsule(float3 a, float3 b, float radius),
Cylinder(float radius, float halfHeight),
Plane(float3 normal, float offset),
/// Evaluates signed distance for this shape at point p.
eval distance :: (float3 p) -> float {
Sphere(radius): sd_sphere(p, radius)
Box(halfExtents): sd_box(p, halfExtents)
RoundBox(halfExtents, radius): sd_round_box(p, halfExtents, radius)
Torus(majorRadius, minorRadius): sd_torus(p, majorRadius, minorRadius)
Capsule(a, b, radius): sd_capsule(p, a, b, radius)
Cylinder(radius, halfHeight): sd_cylinder(p, radius, halfHeight)
Plane(normal, offset): sd_plane(p, normal, offset)
}
/// Estimates a normal from central differences.
eval normal :: (float3 p, float eps) -> float3 {
float3 ex = float3(eps, 0.0, 0.0);
float3 ey = float3(0.0, eps, 0.0);
float3 ez = float3(0.0, 0.0, eps);
return Math::safe_normalize(float3(
self.distance(p + ex) - self.distance(p - ex),
self.distance(p + ey) - self.distance(p - ey),
self.distance(p + ez) - self.distance(p - ez)
));
}
}

SDFCombineOp

bwsl
enum SDFCombineOp : int {
Union = 0,
Intersection = 1,
Subtract = 2,
SmoothUnion = 3,
SmoothIntersection = 4,
SmoothSubtract = 5
}

Functions

sd_sphere

Reference: https://iquilezles.org/articles/distfunctions/

bwsl
sd_sphere :: (float3 p, float radius) -> float

sd_box

Reference: https://iquilezles.org/articles/distfunctions/

bwsl
sd_box :: (float3 p, float3 halfExtents) -> float

sd_round_box

Reference: https://iquilezles.org/articles/distfunctions/

bwsl
sd_round_box :: (float3 p, float3 halfExtents, float radius) -> float

sd_torus

Reference: https://en.wikipedia.org/wiki/Torus

bwsl
sd_torus :: (float3 p, float majorRadius, float minorRadius) -> float

sd_capsule

Reference: https://en.wikipedia.org/wiki/Capsule_(geometry)

bwsl
sd_capsule :: (float3 p, float3 a, float3 b, float radius) -> float

sd_cylinder

Reference: https://en.wikipedia.org/wiki/Cylinder

bwsl
sd_cylinder :: (float3 p, float radius, float halfHeight) -> float

sd_plane

Reference: https://en.wikipedia.org/wiki/Plane_(geometry)

bwsl
sd_plane :: (float3 p, float3 normal, float offset) -> float

normal_sphere

Analytic normal for a sphere centered at the origin.

bwsl
normal_sphere :: (float3 p) -> float3

normal_plane

Analytic normal for a plane.

bwsl
normal_plane :: (float3 normal) -> float3

translate

Moves the SDF sample point into a translated object's local space.

bwsl
translate :: (float3 p, float3 offset) -> float3

scale_uniform

Uniformly scales the SDF sample point. Multiply returned distances by scale.

bwsl
scale_uniform :: (float3 p, float scale) -> float3

repeat

Reference: https://iquilezles.org/articles/distfunctions/

bwsl
repeat :: (float3 p, float3 spacing) -> float3

repeat_xz

Repeats the sample point on XZ while leaving Y unchanged.

bwsl
repeat_xz :: (float3 p, float2 spacing) -> float3

op_union

Union of two signed distances.

bwsl
op_union :: (float a, float b) -> float

op_intersection

Intersection of two signed distances.

bwsl
op_intersection :: (float a, float b) -> float

op_subtract

Difference of signed distance a minus b.

bwsl
op_subtract :: (float a, float b) -> float

smooth_union

Reference: https://iquilezles.org/articles/smin/

bwsl
smooth_union :: (float a, float b, float k) -> float

smooth_intersection

Reference: https://iquilezles.org/articles/smin/

bwsl
smooth_intersection :: (float a, float b, float k) -> float

smooth_subtract

Reference: https://iquilezles.org/articles/smin/

bwsl
smooth_subtract :: (float a, float b, float k) -> float

combine

Smooth operations use k as the blend radius; hard operations ignore k.

bwsl
combine :: (SDFCombineOp op, float a, float b, float k) -> float

soft_mask

Returns a soft inside/outside mask for distance d.

bwsl
soft_mask :: (float d, float feather) -> float

contour

Returns a contour line mask around multiples of spacing.

bwsl
contour :: (float d, float spacing, float width) -> float

distance_color

Returns a simple surface color blend based on signed distance.

bwsl
distance_color :: (float d, float bandWidth, float3 insideColor, float3 outsideColor) -> float3

make_ray

Builds a ray and safely normalizes its direction.

bwsl
make_ray :: (float3 origin, float3 direction) -> Ray

raymarch_shape

Reference: https://en.wikipedia.org/wiki/Ray_marching

bwsl
raymarch_shape :: (SDFShape shape, Ray ray, float minDistance, float maxDistance, float hitEpsilon, int maxSteps) -> RaymarchResult

raymarch_sphere

Convenience wrapper for the common single-sphere case.

bwsl
raymarch_sphere :: (float radius, Ray ray, float minDistance, float maxDistance, float hitEpsilon, int maxSteps) -> RaymarchResult

Source

Generated from compiler-reference/modules/SDF.bwsl.