<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Gaurav Tejpal</title>
    <description>The latest articles on DEV Community by Gaurav Tejpal (@gaurav_tejpal_5e0d2f50499).</description>
    <link>https://dev.to/gaurav_tejpal_5e0d2f50499</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1561306%2F5f1528ce-9513-450d-9ab1-51829c3217ce.png</url>
      <title>DEV Community: Gaurav Tejpal</title>
      <link>https://dev.to/gaurav_tejpal_5e0d2f50499</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/gaurav_tejpal_5e0d2f50499"/>
    <language>en</language>
    <item>
      <title>I built a browser-based SDF geometry studio that compiles node graphs to GLSL at runtime</title>
      <dc:creator>Gaurav Tejpal</dc:creator>
      <pubDate>Thu, 09 Jul 2026 07:11:16 +0000</pubDate>
      <link>https://dev.to/gaurav_tejpal_5e0d2f50499/i-built-a-browser-based-sdf-geometry-studio-that-compiles-node-graphs-to-glsl-at-runtime-1bij</link>
      <guid>https://dev.to/gaurav_tejpal_5e0d2f50499/i-built-a-browser-based-sdf-geometry-studio-that-compiles-node-graphs-to-glsl-at-runtime-1bij</guid>
      <description>&lt;p&gt;For the past several months I've been building Isoline, a browser-based studio for designing procedural geometry with Signed Distance Functions (SDFs).&lt;/p&gt;

&lt;p&gt;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.&lt;br&gt;
The application runs entirely in the browser—no installation required.&lt;/p&gt;

&lt;p&gt;The live demo is available at&lt;br&gt;
&lt;a href="https://isoline-studio.netlify.app" rel="noopener noreferrer"&gt;https://isoline-studio.netlify.app&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The source code is available at&lt;br&gt;
&lt;a href="https://github.com/Santideva/Isoline" rel="noopener noreferrer"&gt;https://github.com/Santideva/Isoline&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fp9rz42mlpf0lkyqny8hq.jpeg" alt="The Isoline node-based editing interface" width="800" height="449"&gt;
&lt;/h2&gt;
&lt;h2&gt;
  
  
  Why SDFs?
&lt;/h2&gt;

&lt;p&gt;Most modelling software represents geometry as polygon meshes.&lt;br&gt;
SDFs represent geometry differently. Instead of vertices and triangles, a shape is simply a mathematical function&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight glsl"&gt;&lt;code&gt;&lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;sdf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;vec3&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;that returns the signed distance from a point to the nearest surface.&lt;br&gt;
Because shapes are functions rather than meshes, operations like smooth unions, differences, noise displacement and symmetry become mathematical function composition rather than mesh editing.&lt;br&gt;
That opens up a different modelling workflow which is especially useful for procedural forms.&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frupfd5zm2euz6p310ar1.jpeg" alt="Example procedural node graph used to generate geometry" width="800" height="449"&gt;
&lt;/h2&gt;
&lt;h2&gt;
  
  
  Architecture
&lt;/h2&gt;

&lt;p&gt;The application consists of four major parts.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  visual node editor &lt;/li&gt;
&lt;li&gt;  graph compiler &lt;/li&gt;
&lt;li&gt;  rendering system &lt;/li&gt;
&lt;li&gt;  export pipeline 
Every node emits a typed GLSL function.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight glsl"&gt;&lt;code&gt;&lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;vec2&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;or&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight glsl"&gt;&lt;code&gt;&lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;vec3&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;depending on whether the node represents a 2D or 3D SDF.&lt;br&gt;
When the graph changes, the compiler&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  topologically sorts the graph &lt;/li&gt;
&lt;li&gt;  resolves dependencies &lt;/li&gt;
&lt;li&gt;  emits helper functions &lt;/li&gt;
&lt;li&gt;  generates the final sceneSDF() &lt;/li&gt;
&lt;li&gt;  recompiles the shader 
The graph itself becomes the shader.
There is no intermediate representation or custom scripting language.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3jh9piwbglfoh3648d94.jpeg" alt="Geometry exported as standalone GLSL shader" width="799" height="528"&gt;
&lt;/h2&gt;

&lt;h2&gt;
  
  
  Engineering Challenges
&lt;/h2&gt;

&lt;p&gt;A few problems turned out to be more interesting than I expected.&lt;/p&gt;

&lt;h3&gt;
  
  
  Mixed 2D / 3D graphs
&lt;/h3&gt;

&lt;p&gt;Nodes like Extrude and Revolve connect 2D graphs to 3D graphs.&lt;br&gt;
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.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mixed-dimension graphs therefore work without manual mode switching.
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Duplicate GLSL helper functions
&lt;/h3&gt;

&lt;p&gt;Multiple Noise Displacement nodes originally generated duplicate helper functions.&lt;br&gt;
GLSL rejected shaders with errors like&lt;br&gt;
function already has a body&lt;/p&gt;

&lt;h2&gt;
  
  
  The solution was moving all shared helper functions into a common shader preamble emitted exactly once.
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Adaptive ray marching
&lt;/h3&gt;

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

&lt;h2&gt;
  
  
  The expensive analysis never runs during animation.
&lt;/h2&gt;

&lt;h3&gt;
  
  
  CPU and GPU share the same graph
&lt;/h3&gt;

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

&lt;h2&gt;
  
  
  If it renders correctly, it can also be exported as an STL.
&lt;/h2&gt;

&lt;h2&gt;
  
  
  Current capabilities
&lt;/h2&gt;

&lt;p&gt;Version 1 includes&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  2D primitives &lt;/li&gt;
&lt;li&gt;  3D primitives &lt;/li&gt;
&lt;li&gt;  transforms &lt;/li&gt;
&lt;li&gt;  symmetry operations &lt;/li&gt;
&lt;li&gt;  smooth blending &lt;/li&gt;
&lt;li&gt;  Schur blending &lt;/li&gt;
&lt;li&gt;  IFS blending &lt;/li&gt;
&lt;li&gt;  CPU contour rendering &lt;/li&gt;
&lt;li&gt;  GPU SDF rendering &lt;/li&gt;
&lt;li&gt;  full ray marching &lt;/li&gt;
&lt;li&gt;  PNG export &lt;/li&gt;
&lt;li&gt;  GLSL export &lt;/li&gt;
&lt;li&gt;  STL export &lt;/li&gt;
&lt;li&gt;  scene save/load &lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flbo8dqdhpdw8lz1cw0nv.png" alt="Binary STL exported from the procedural scene" width="800" height="611"&gt;
&lt;/h2&gt;

&lt;h2&gt;
  
  
  Example outputs
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fadetfhdqifwbz22oqwb2.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fadetfhdqifwbz22oqwb2.jpeg" alt="Repeated procedural geometry demonstrating composition and instancing" width="800" height="449"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fm9wvrlwxckuvlk49kwcq.jpeg" alt="Example of procedural lattice generated from composed SDF primitives" width="800" height="449"&gt;
&lt;/h2&gt;

&lt;h2&gt;
  
  
  What's missing?
&lt;/h2&gt;

&lt;p&gt;Version 1 deliberately focuses on the core workflow.&lt;br&gt;
Some areas still need work.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  better material system &lt;/li&gt;
&lt;li&gt;  animation graph &lt;/li&gt;
&lt;li&gt;  additional bridge nodes &lt;/li&gt;
&lt;li&gt;  terrain generation &lt;/li&gt;
&lt;li&gt;  reusable subgraphs &lt;/li&gt;
&lt;li&gt;  improved camera system &lt;/li&gt;
&lt;li&gt;  more shader export targets &lt;/li&gt;
&lt;li&gt;  broader positioning system
Those are already planned for future releases.
---&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;h2&gt;
  
  
  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.
&lt;/h2&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Live demo: &lt;a href="https://isoline-studio.netlify.app" rel="noopener noreferrer"&gt;https://isoline-studio.netlify.app&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Source code: &lt;a href="https://github.com/Santideva/Isoline" rel="noopener noreferrer"&gt;https://github.com/Santideva/Isoline&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;YouTube walkthrough: &lt;a href="https://youtu.be/dGRmIoLHyaw?si=j9elJEZS26qRGX2k" rel="noopener noreferrer"&gt;https://youtu.be/dGRmIoLHyaw?si=j9elJEZS26qRGX2k&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Product Hunt launch: &lt;a href="https://www.producthunt.com/products/isoline?utm_source=other&amp;amp;utm_medium=social" rel="noopener noreferrer"&gt;https://www.producthunt.com/products/isoline?utm_source=other&amp;amp;utm_medium=social&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>webgl</category>
      <category>glsl</category>
      <category>javascript</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Beginner</title>
      <dc:creator>Gaurav Tejpal</dc:creator>
      <pubDate>Tue, 19 Nov 2024 02:50:01 +0000</pubDate>
      <link>https://dev.to/gaurav_tejpal_5e0d2f50499/beginner-n15</link>
      <guid>https://dev.to/gaurav_tejpal_5e0d2f50499/beginner-n15</guid>
      <description></description>
      <category>beginners</category>
    </item>
  </channel>
</rss>
