How to Create Implicit CAD Models Using GLSL Signed-Distance Fields
The earthtojake/text-to-cad repository generates implicit CAD models by parsing GLSL-style signed-distance field (SDF) expressions into executable JavaScript functions, automatically calculating geometric bounds, and extracting triangle meshes via a marching-cubes algorithm—enabling browser-based solid modeling without external CAD kernels.
This open-source toolkit implements a declarative, shader-inspired pipeline where you define geometry through mathematical distance functions rather than traditional boundary representations. By compiling GLSL-like syntax into JavaScript evaluators, the system samples 3D space to reconstruct surfaces as ready-to-export meshes.
Understanding the GLSL SDF Pipeline
The architecture follows three distinct stages that transform mathematical expressions into printable geometry. Each stage corresponds to specific modules within the packages/implicitjs/src/lib/implicitCad/ directory.
SDF Definition and Compilation occurs in sdfEvaluator.js, which implements vector mathematics (vec3, length, dot, cross), swizzle operations (p.x, p.xyz), and utility functions (clamp, smoothstep, mix) that mirror GLSL syntax. This module translates your distance function into a callable JavaScript closure that returns the signed distance at any 3D coordinate.
Parameter Normalization and Bounds Estimation handled by model.js manages input validation and spatial boundaries. When you specify bounds: "auto", the system invokes sampleAutoBounds and estimateAutoBoundsStartRadius to scan the SDF and determine a tight bounding box, ensuring the marching-cubes algorithm only processes regions containing actual surface geometry.
Mesh Extraction orchestrated by render.js and mesh.js samples the signed-distance field onto a 3D texture grid, then applies the marching-cubes algorithm to generate indexed triangle geometry with proper vertex normals.
Step-by-Step Implementation
Step 1: Define the Signed-Distance Function
Write your geometry using GLSL-style expressions. The DSL supports standard S primitives including sphere, box, and boolean operations like union and subtract, along with transformations such as rotate and translate.
// Define a sphere with radius 10 using GLSL syntax
const sdfSource = `
float sdf(vec3 p) {
return length(p) - 10.0;
}
`;
Step 2: Compile the SDF Evaluator
Import createImplicitCadSdfEvaluator from sdfEvaluator.js to parse your GLSL code into an executable JavaScript function.
import { createImplicitCadSdfEvaluator } from
'@earthtojake/text-to-cad/implicitjs/lib/implicitCad/sdfEvaluator.js';
// Compile the DSL into a callable function
const sdf = createImplicitCadSdfEvaluator(sdfSource);
// Test the evaluator at a specific point
const distance = sdf({ x: 5, y: 0, z: 0 }); // Returns -5.0 (inside sphere)
The evaluator handles vector construction, swizzle access patterns, and mathematical operations through intermediate representations that mirror GPU shader execution.
Step 3: Generate the Model with Automatic Bounds
Use createImplicitCadModel from model.js to handle parameter normalization and automatic boundary detection. This eliminates manual bounding box calculations.
import { createImplicitCadModel } from
'@earthtojake/text-to-cad/implicitjs/lib/implicitCad/model.js';
const model = createImplicitCadModel({
sdf,
definition: {
parameters: [] // Schema for configurable parameters
},
context: {
params: {},
bounds: "auto" // Triggers automatic bounds estimation
}
});
// The model object now contains mesh data ready for extraction
When bounds is set to "auto", the implementation runs sampleAutoBounds to iteratively expand a search radius until it detects the surface transition (sign change in the distance field), then adds appropriate margins.
Step 4: Extract and Export the Mesh
The resulting mesh contains indexed positions, faces, and normals. Use the export utilities to serialize into standard CAD formats.
import { exportModel } from
'@earthtojake/text-to-cad/implicitjs/lib/implicitCad/export.js';
// Export as binary GLB for immediate 3D viewer display
const glbBuffer = exportModel(model.mesh, { format: 'glb' });
// Alternative: Export as OBJ for traditional CAD workflows
const objString = exportModel(model.mesh, { format: 'obj' });
Core Files and Architecture
sdfEvaluator.js: Implements GLSL vector math (vec,vec2/3/4), swizzle handling (getSwizzle,setSwizzle), and utility functions. Compiles DSL strings into JavaScript evaluators.model.js: Normalizes skill parameters, manages schema validation, and implements automatic bounds detection viaestimateAutoBoundsStartRadius.render.js: Orchestrates GPU-accelerated sampling of the distance field into 3D textures.mesh.js: Contains the marching-cubes triangulation algorithm that converts volumetric distance data into indexed triangle meshes.export.js: Serializes mesh data to GLB, OBJ, and STL formats with proper material indexing.
Summary
- GLSL Compatibility: The
sdfEvaluator.jsmodule provides shader-style vector operations and swizzling, allowing direct porting of existing SDF recipes from ShaderToy or GLSL references. - Automatic Bounding: The
model.jsimplementation eliminates manual bounding box configuration throughsampleAutoBounds, scanning the implicit field to find tight geometric limits. - Browser-Native Execution: The entire pipeline runs in JavaScript without WebAssembly dependencies or external CAD kernels, enabling client-side generation and immediate visualization.
- Standard Export Formats: Generated meshes export to GLB, OBJ, and STL through
export.js, integrating with standard 3D printing and CAD workflows.
Frequently Asked Questions
What is a signed-distance field in CAD modeling?
A signed-distance field (SDF) is a mathematical function that returns the shortest distance from any point in space to the nearest surface of a geometric shape. Negative values indicate points inside the object, positive values indicate outside, and zero represents the exact surface boundary. In the text-to-cad repository, you define these functions using GLSL-style syntax that gets compiled into JavaScript evaluators.
How does automatic bounds detection work?
The automatic bounds system in model.js uses estimateAutoBoundsStartRadius to calculate an initial search sphere based on the SDF's expected scale, then iteratively samples the distance field using sampleAutoBounds to expand the bounding box until it detects a sign change indicating surface geometry. This ensures the marching-cubes algorithm only processes voxels that actually contain mesh data, optimizing memory usage and processing time.
Can I use existing GLSL SDF code with this library?
Yes. The sdfEvaluator.js parser supports standard GLSL constructs including vector types (vec2, vec3, vec4), swizzle accessors (p.xy, p.xyz), and common mathematical functions (length, distance, dot, cross, normalize, clamp, smoothstep). You can typically copy SDF functions from existing GLSL references or ShaderToy with minimal syntax adjustments, as the evaluator implements the same mathematical primitives used in GPU shaders.
What file formats can I export from the implicit CAD models?
The export.js module supports GLB (Binary glTF), OBJ (Wavefront), and STL (Stereolithography) formats. The GLB export preserves material information and vertex normals for immediate web display, while OBJ and STL provide compatibility with traditional CAD software and 3D printing slicers. All exports use the indexed triangle mesh generated by the marching-cubes implementation in mesh.js.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →