SDF Module
Signed-distance primitives, composition helpers, debug masks, and raymarching helpers.
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 PlaygroundSigned-distance primitives, composition helpers, debug masks, and raymarching helpers.
Import
import SDF
This module imports: Math.
Constants
None.
Structs
Ray
struct Ray {
float3 origin;
float3 direction;
};
RaymarchResult
struct RaymarchResult {
bool hit;
int steps;
float distance;
float3 position;
float surfaceDistance;
};
Enums
SDFShape
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
enum SDFCombineOp : int {
Union = 0,
Intersection = 1,
Subtract = 2,
SmoothUnion = 3,
SmoothIntersection = 4,
SmoothSubtract = 5
}
Functions
sd_sphere
Reference: https://iquilezles.org/articles/distfunctions/
sd_sphere :: (float3 p, float radius) -> float
sd_box
Reference: https://iquilezles.org/articles/distfunctions/
sd_box :: (float3 p, float3 halfExtents) -> float
sd_round_box
Reference: https://iquilezles.org/articles/distfunctions/
sd_round_box :: (float3 p, float3 halfExtents, float radius) -> float
sd_torus
Reference: https://en.wikipedia.org/wiki/Torus
sd_torus :: (float3 p, float majorRadius, float minorRadius) -> float
sd_capsule
Reference: https://en.wikipedia.org/wiki/Capsule_(geometry)
sd_capsule :: (float3 p, float3 a, float3 b, float radius) -> float
sd_cylinder
Reference: https://en.wikipedia.org/wiki/Cylinder
sd_cylinder :: (float3 p, float radius, float halfHeight) -> float
sd_plane
Reference: https://en.wikipedia.org/wiki/Plane_(geometry)
sd_plane :: (float3 p, float3 normal, float offset) -> float
normal_sphere
Analytic normal for a sphere centered at the origin.
normal_sphere :: (float3 p) -> float3
normal_plane
Analytic normal for a plane.
normal_plane :: (float3 normal) -> float3
translate
Moves the SDF sample point into a translated object's local space.
translate :: (float3 p, float3 offset) -> float3
scale_uniform
Uniformly scales the SDF sample point. Multiply returned distances by scale.
scale_uniform :: (float3 p, float scale) -> float3
repeat
Reference: https://iquilezles.org/articles/distfunctions/
repeat :: (float3 p, float3 spacing) -> float3
repeat_xz
Repeats the sample point on XZ while leaving Y unchanged.
repeat_xz :: (float3 p, float2 spacing) -> float3
op_union
Union of two signed distances.
op_union :: (float a, float b) -> float
op_intersection
Intersection of two signed distances.
op_intersection :: (float a, float b) -> float
op_subtract
Difference of signed distance a minus b.
op_subtract :: (float a, float b) -> float
smooth_union
Reference: https://iquilezles.org/articles/smin/
smooth_union :: (float a, float b, float k) -> float
smooth_intersection
Reference: https://iquilezles.org/articles/smin/
smooth_intersection :: (float a, float b, float k) -> float
smooth_subtract
Reference: https://iquilezles.org/articles/smin/
smooth_subtract :: (float a, float b, float k) -> float
combine
Smooth operations use k as the blend radius; hard operations ignore k.
combine :: (SDFCombineOp op, float a, float b, float k) -> float
soft_mask
Returns a soft inside/outside mask for distance d.
soft_mask :: (float d, float feather) -> float
contour
Returns a contour line mask around multiples of spacing.
contour :: (float d, float spacing, float width) -> float
distance_color
Returns a simple surface color blend based on signed distance.
distance_color :: (float d, float bandWidth, float3 insideColor, float3 outsideColor) -> float3
make_ray
Builds a ray and safely normalizes its direction.
make_ray :: (float3 origin, float3 direction) -> Ray
raymarch_shape
Reference: https://en.wikipedia.org/wiki/Ray_marching
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.
raymarch_sphere :: (float radius, Ray ray, float minDistance, float maxDistance, float hitEpsilon, int maxSteps) -> RaymarchResult
Source
Generated from compiler-reference/modules/SDF.bwsl.