Writing WebGL Shaders in Pure Coni Lisp!
In our previous post, we showcased the raw power of Coni WASM by orchestrating an 80,000 particle WebGL matrix. But there was always one lingering annoyance in the WebGL pipeline: the shaders themselves.
If you’ve ever written WebGL code, you know the drill. You end up writing your Vertex and Fragment shaders as massive, messy string literals concatenated across your codebase. You lose syntax highlighting, formatting, and—most tragically for Lisp hackers—you lose structural editing (Paredit/Slurp/Barf).
Today, we’re thrilled to announce we’ve conquered that final frontier with the new libs/webgl/src/glsl.coni library.
You can now write your GLSL shaders entirely in Coni’s native Lisp syntax.
Enter defshader
By leveraging Coni’s powerful AST and macro system, we built defshader. It takes standard Lisp forms, types, and mathematical operations, and automatically transpiles them into strict GLSL before they hit the GPU.
Just look at how beautifully this Fragment Shader is written for our Amplifocus particle engine:
(require "libs/webgl/src/glsl.coni" :all)
(defshader fs-src
(precision mediump float)
(varying vec4 v_color)
(defn void main []
;; Native math and coordinate mapping!
(set vec2 coord (- gl_PointCoord (vec2 0.5 0.5)))
(set float dist (length coord))
(if (> dist 0.5)
(discard))
;; Glow calculations using Lisp S-expressions
(set float glow (- 1.0 (* dist 2.0)))
(set vec4 final_color (* v_color glow))
(set gl_FragColor final_color)))
Why is this a game changer?
- No More String Literals: Your shaders are first-class code. They format perfectly with the rest of your application.
- AST-Level Validation: The Coni compiler can parse and validate your shader structure before it ever attempts to compile the WebGL program in the browser.
- Structural Editing: You can slurp, barf, and manipulate your complex GPU math using standard Lisp structural editing tools. Try doing that with a C-style GLSL string!
- Seamless Integration: Compiling it to a usable WebGL shader is as simple as calling our
core-gl/gl-shaderfunction:(core-gl/gl-shader gl (.-FRAGMENT_SHADER gl) fs-src).
A Full-Stack Lisp for the Browser
With this update, the pipeline is complete. From DOM manipulation with reframe, to WebAudio synthesis, to WASM float buffers, and now down to the actual GPU vertex transformations—it is 100% Coni.
No raw JavaScript. No raw GLSL. Just pure, unadulterated Lisp running at blistering speeds.
We’ve already deployed these new Lisp shaders in our deep-focus-webgl app. If you’re building high-performance interactive experiences in the browser, it’s time to give Coni a spin!