Liking cljdoc? Tell your friends :D

warpaint.dsl

Minimal s-expression shader DSL for Clojure.

Emits GLSL 450 source from Clojure data, then compiles to SPIR-V via warpaint.compiler (shaderc in-process, glslc fallback).

Quick start

(require '[warpaint.dsl :refer [defshader emit-glsl compile-shader]])

;; Define a shader var — compiles to SPIR-V at load time
(defshader my-vert :vertex
  {:inputs  [{:name :in-pos :type :vec2 :location 0}]
   :outputs [{:name :frag-color :type :vec4 :location 0}]
   :push-constants [{:name :translation :type :vec2}
                    {:name :rotation    :type :float}
                    {:name :padding     :type :float}
                    {:name :color       :type :vec4}]}
  (let [^float c       (cos (.rotation pc))
        ^float s       (sin (.rotation pc))
        ^vec2  rotated (vec2 (- (* (.x in-pos) c) (* (.y in-pos) s))
                             (+ (* (.x in-pos) s) (* (.y in-pos) c)))
        ^vec2  final   (+ rotated (.translation pc))]
    (set! gl-Position (vec4 final 0.0 1.0))
    (set! frag-color (.color pc))))

;; my-vert is now a java.nio.ByteBuffer containing SPIR-V

Shader descriptor map

compile-shader and emit-glsl accept a map with these keys:

KeyTypeDescription
:stagekeyword:vertex | :fragment | :compute
:inputsvec[{:name :kw :type :glsl-type :location N}]
:outputsvecsame shape as :inputs
:push-constantsvec[{:name :kw :type :glsl-type}]
:uniformsvec[{:name :kw :type :glsl-type :set N :binding N}]
:const-arraysvec[{:name :kw :type :glsl-type :size N :values [...]}]
:mainvecs-expression forms for void main() {}

Supported GLSL types (as keywords)

:float :int :uint :bool :vec2 :vec3 :vec4 :mat2 :mat3 :mat4 :ivec2 :ivec3 :ivec4 :sampler2D

Expression syntax

Clojure formEmits
(+ a b)(a + b)
(= a b)(a == b)
(.x v)v.x
(.translation pc)pc.translation
(aget arr i)arr[i]
(set! dest val)dest = val
(vec4 x y z w)vec4(x, y, z, w)
(if cond a b)(cond ? a : b)
(when cond body…)if (cond) { … }
(do stmts…)statements
(let [^T n v] …)T n = v; …
gl-Positiongl_Position
gl-VertexIndexgl_VertexIndex
gl-FragCoordgl_FragCoord
gl-PointSizegl_PointSize

Identifiers are kebab→camelCase: :frag-colorfragColor.

Minimal s-expression shader DSL for Clojure.

Emits GLSL 450 source from Clojure data, then compiles to SPIR-V via
warpaint.compiler (shaderc in-process, glslc fallback).

## Quick start

```clojure
(require '[warpaint.dsl :refer [defshader emit-glsl compile-shader]])

;; Define a shader var — compiles to SPIR-V at load time
(defshader my-vert :vertex
  {:inputs  [{:name :in-pos :type :vec2 :location 0}]
   :outputs [{:name :frag-color :type :vec4 :location 0}]
   :push-constants [{:name :translation :type :vec2}
                    {:name :rotation    :type :float}
                    {:name :padding     :type :float}
                    {:name :color       :type :vec4}]}
  (let [^float c       (cos (.rotation pc))
        ^float s       (sin (.rotation pc))
        ^vec2  rotated (vec2 (- (* (.x in-pos) c) (* (.y in-pos) s))
                             (+ (* (.x in-pos) s) (* (.y in-pos) c)))
        ^vec2  final   (+ rotated (.translation pc))]
    (set! gl-Position (vec4 final 0.0 1.0))
    (set! frag-color (.color pc))))

;; my-vert is now a java.nio.ByteBuffer containing SPIR-V
```

## Shader descriptor map

`compile-shader` and `emit-glsl` accept a map with these keys:

| Key               | Type    | Description |
|-------------------|---------|-------------|
| `:stage`          | keyword | `:vertex` \| `:fragment` \| `:compute` |
| `:inputs`         | vec     | `[{:name :kw :type :glsl-type :location N}]` |
| `:outputs`        | vec     | same shape as `:inputs` |
| `:push-constants` | vec     | `[{:name :kw :type :glsl-type}]` |
| `:uniforms`       | vec     | `[{:name :kw :type :glsl-type :set N :binding N}]` |
| `:const-arrays`   | vec     | `[{:name :kw :type :glsl-type :size N :values [...]}]` |
| `:main`           | vec     | s-expression forms for `void main() {}` |

## Supported GLSL types (as keywords)

`:float` `:int` `:uint` `:bool` `:vec2` `:vec3` `:vec4`
`:mat2` `:mat3` `:mat4` `:ivec2` `:ivec3` `:ivec4` `:sampler2D`

## Expression syntax

| Clojure form         | Emits            |
|----------------------|------------------|
| `(+ a b)`            | `(a + b)`        |
| `(= a b)`            | `(a == b)`       |
| `(.x v)`             | `v.x`            |
| `(.translation pc)`  | `pc.translation` |
| `(aget arr i)`       | `arr[i]`         |
| `(set! dest val)`    | `dest = val`     |
| `(vec4 x y z w)`     | `vec4(x, y, z, w)` |
| `(if cond a b)`      | `(cond ? a : b)` |
| `(when cond body…)`  | `if (cond) { … }` |
| `(do stmts…)`        | statements       |
| `(let [^T n v] …)`   | `T n = v; …`     |
| `gl-Position`        | `gl_Position`    |
| `gl-VertexIndex`     | `gl_VertexIndex` |
| `gl-FragCoord`       | `gl_FragCoord`   |
| `gl-PointSize`       | `gl_PointSize`   |

Identifiers are kebab→camelCase: `:frag-color` → `fragColor`.
raw docstring

compile-shaderclj

(compile-shader descriptor)

Compile a shader descriptor map to a SPIR-V ByteBuffer. Writes a temporary .glsl file, compiles with shaderc (glslc fallback), and returns a java.nio.ByteBuffer.

See namespace docstring for descriptor map keys.

Compile a shader descriptor map to a SPIR-V ByteBuffer.
Writes a temporary .glsl file, compiles with shaderc (glslc fallback),
and returns a java.nio.ByteBuffer.

See namespace docstring for descriptor map keys.
sourceraw docstring

defshadercljmacro

(defshader shader-name stage descriptor & body)

Define a named shader var. Compiles to a SPIR-V ByteBuffer at load time.

Usage: (defshader my-vert :vertex {:inputs [{:name :in-pos :type :vec2 :location 0}] :outputs [{:name :frag-color :type :vec4 :location 0}] :push-constants [{:name :color :type :vec4}]} (set! gl-Position (vec4 (.translation pc) 0.0 1.0)) (set! frag-color (.color pc)))

body forms become the :main of the descriptor. The resulting var holds a java.nio.ByteBuffer of SPIR-V.

Define a named shader var. Compiles to a SPIR-V ByteBuffer at load time.

Usage:
  (defshader my-vert :vertex
    {:inputs  [{:name :in-pos :type :vec2 :location 0}]
     :outputs [{:name :frag-color :type :vec4 :location 0}]
     :push-constants [{:name :color :type :vec4}]}
    (set! gl-Position (vec4 (.translation pc) 0.0 1.0))
    (set! frag-color (.color pc)))

`body` forms become the :main of the descriptor.
The resulting var holds a java.nio.ByteBuffer of SPIR-V.
sourceraw docstring

emit-glslclj

(emit-glsl {:keys [inputs outputs push-constants uniforms const-arrays main]})

Emit a GLSL 450 string from a shader descriptor map. Does not compile — useful for inspecting generated source or testing.

See namespace docstring for descriptor map keys.

Emit a GLSL 450 string from a shader descriptor map.
Does not compile — useful for inspecting generated source or testing.

See namespace docstring for descriptor map keys.
sourceraw docstring

load-ednclj

(load-edn path)

Load a shader descriptor from an EDN file and compile it to SPIR-V. Stage is inferred from the file extension (.vert / .frag / .comp). Returns a java.nio.ByteBuffer.

Example: (warpaint.dsl/load-edn "shaders/my-shader.vert.edn")

Load a shader descriptor from an EDN file and compile it to SPIR-V.
Stage is inferred from the file extension (.vert / .frag / .comp).
Returns a java.nio.ByteBuffer.

Example:
  (warpaint.dsl/load-edn "shaders/my-shader.vert.edn")
sourceraw docstring

cljdoc builds & hosts documentation for Clojure/Script libraries

Keyboard shortcuts
Ctrl+kJump to recent docs
Move to previous article
Move to next article
Ctrl+/Jump to the search field
× close