DEV Community

Cover image for I built a browser-based SDF geometry studio that compiles node graphs to GLSL at runtime
Gaurav Tejpal
Gaurav Tejpal

Posted on

I built a browser-based SDF geometry studio that compiles node graphs to GLSL at runtime

For the past several months I've been building Isoline, a browser-based studio for designing procedural geometry with Signed Distance Functions (SDFs).

The project sits somewhere between writing raw GLSL by hand and using a conventional 3D package. Instead of writing shader code directly, you build a graph of SDF operations visually. That graph is then compiled into GLSL fragment shader source at runtime.
The application runs entirely in the browser—no installation required.

The live demo is available at
https://isoline-studio.netlify.app

The source code is available at
https://github.com/Santideva/Isoline

The Isoline node-based editing interface

Why SDFs?

Most modelling software represents geometry as polygon meshes.
SDFs represent geometry differently. Instead of vertices and triangles, a shape is simply a mathematical function

float sdf(vec3 p)
Enter fullscreen mode Exit fullscreen mode

that returns the signed distance from a point to the nearest surface.
Because shapes are functions rather than meshes, operations like smooth unions, differences, noise displacement and symmetry become mathematical function composition rather than mesh editing.
That opens up a different modelling workflow which is especially useful for procedural forms.

Example procedural node graph used to generate geometry

Architecture

The application consists of four major parts.

  • visual node editor
  • graph compiler
  • rendering system
  • export pipeline Every node emits a typed GLSL function.
float fn(vec2 p)
Enter fullscreen mode Exit fullscreen mode

or

float fn(vec3 p)
Enter fullscreen mode Exit fullscreen mode

depending on whether the node represents a 2D or 3D SDF.
When the graph changes, the compiler

  • topologically sorts the graph
  • resolves dependencies
  • emits helper functions
  • generates the final sceneSDF()
  • recompiles the shader The graph itself becomes the shader. There is no intermediate representation or custom scripting language.

Geometry exported as standalone GLSL shader

Engineering Challenges

A few problems turned out to be more interesting than I expected.

Mixed 2D / 3D graphs

Nodes like Extrude and Revolve connect 2D graphs to 3D graphs.
Instead of asking the user which mode they're in, the compiler walks the graph recursively to determine whether the upstream node produces a 2D or 3D SDF, then generates the appropriate GLSL signature automatically.

Mixed-dimension graphs therefore work without manual mode switching.

Duplicate GLSL helper functions

Multiple Noise Displacement nodes originally generated duplicate helper functions.
GLSL rejected shaders with errors like
function already has a body

The solution was moving all shared helper functions into a common shader preamble emitted exactly once.

Adaptive ray marching

Some operations violate the assumptions of sphere tracing.
Difference operations, aggressive space warps and heavy displacement all require smaller steps and more iterations.
Rather than asking users to tune quality manually, the compiler analyses the graph once after each edit and chooses an appropriate marching profile.

The expensive analysis never runs during animation.

CPU and GPU share the same graph

One goal was avoiding two independent implementations.
The CPU renderer, GLSL renderer and STL exporter all evaluate the same node graph.
That means a node only has to be implemented once conceptually.

If it renders correctly, it can also be exported as an STL.

Current capabilities

Version 1 includes

  • 2D primitives
  • 3D primitives
  • transforms
  • symmetry operations
  • smooth blending
  • Schur blending
  • IFS blending
  • CPU contour rendering
  • GPU SDF rendering
  • full ray marching
  • PNG export
  • GLSL export
  • STL export
  • scene save/load

Binary STL exported from the procedural scene

Example outputs

Repeated procedural geometry demonstrating composition and instancing

Example of procedural lattice generated from composed SDF primitives

What's missing?

Version 1 deliberately focuses on the core workflow.
Some areas still need work.

  • better material system
  • animation graph
  • additional bridge nodes
  • terrain generation
  • reusable subgraphs
  • improved camera system
  • more shader export targets
  • broader positioning system Those are already planned for future releases. ---

Conclusion

Building Isoline has been an opportunity to explore a different approach to procedural modelling—one based on composing mathematical functions rather than editing meshes. Version 1 focuses on establishing that workflow, and there is still plenty to improve, but it's reached the point where I'd like to see how other developers and artists use it.

If you're interested in procedural modelling, GLSL, ray marching, browser graphics or node-based tools, I'd genuinely appreciate your feedback. Every suggestion goes directly onto the roadmap.

Resources

Top comments (0)