Rewrites Clojure forms into code that builds a TSL node graph.
Pure form -> form functions with no dependency on the ClojureScript
analyzer, so the same compiler backs both the shadow-cljs macros in
threeagent.tsl and the SCI macros in threeagent.tsl.sci.
The emitted code only calls plain functions in threeagent.tsl (no ^js
interop), which keeps it valid under advanced compilation and in SCI.
Symbol resolution inside shader code:
&env and bindings inside the form) always win+, <, if, set!, dotimes, ...) are
rewritten to TSL-aware runtime callspositionLocal) or
kebab-case (position-local), become TSL references(clj ...)Rewrites Clojure forms into code that builds a TSL node graph. Pure form -> form functions with no dependency on the ClojureScript analyzer, so the same compiler backs both the shadow-cljs macros in `threeagent.tsl` and the SCI macros in `threeagent.tsl.sci`. The emitted code only calls plain functions in `threeagent.tsl` (no `^js` interop), which keeps it valid under advanced compilation and in SCI. Symbol resolution inside shader code: - lexical locals (from `&env` and bindings inside the form) always win - operators and special forms (`+`, `<`, `if`, `set!`, `dotimes`, ...) are rewritten to TSL-aware runtime calls - names exported by three/tsl, in their JS spelling (`positionLocal`) or kebab-case (`position-local`), become TSL references - everything else passes through untouched, as does `(clj ...)`
(compile-compute [opts & body] locals form)(compute {:count n :workgroup-size [64]} & body)
(compute {:count n :workgroup-size [64]} & body)
(compile-form form locals)Compile one form of shader code. locals is a set of symbols bound in the
surrounding scope; they shadow TSL names.
Compile one form of shader code. `locals` is a set of symbols bound in the surrounding scope; they shadow TSL names.
(compile-shader body locals)Compile the body of a shader form. Bodies that use statements are wrapped
in a TSL Fn so If/Loop/assign have a stack to land on.
Compile the body of a `shader` form. Bodies that use statements are wrapped in a TSL Fn so If/Loop/assign have a stack to land on.
(compile-shader-fn fname [params & more] locals form)(shader-fn name? [params] return-type? & body) -> code creating a TSL Fn wrapped in a Clojure function.
(shader-fn name? [params] return-type? & body) -> code creating a TSL Fn wrapped in a Clojure function.
(contains-statement? form)True when form uses a construct that needs a TSL Fn stack.
True when `form` uses a construct that needs a TSL Fn stack.
(env-locals env)Local symbols from a macro &env: ClojureScript analyzer envs keep them
under :locals; SCI and Clojure pass a map keyed by the locals.
Local symbols from a macro `&env`: ClojureScript analyzer envs keep them under :locals; SCI and Clojure pass a map keyed by the locals.
(expand-compute args env form)(expand-defcompute [cname & args] env form)(expand-defshader [fname & fdecl])(expand-defshader-fn [fname & args] env form)(expand-shader body env)(expand-shader-fn args env form)(expand-threading [op x & steps :as form])(kebab js-name)positionLocal -> position-local, TWO_PI -> two-pi, mx_noise_float -> mx-noise-float
positionLocal -> position-local, TWO_PI -> two-pi, mx_noise_float -> mx-noise-float
(parse-params params form)[a :float b :vec3] -> {:syms [a b] :types ["float" "vec3"]} [a b] -> {:syms [a b] :types nil}
[a :float b :vec3] -> {:syms [a b] :types ["float" "vec3"]}
[a b] -> {:syms [a b] :types nil}(pattern-syms pattern)Every symbol bound by a destructuring pattern.
Every symbol bound by a destructuring pattern.
(wgsl-name sym)A WGSL-safe identifier for a Clojure symbol.
A WGSL-safe identifier for a Clojure symbol.
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |