用纯Coni Lisp编写WebGL着色器!
Contents
在上一篇文章中,我们通过编排一个由80,000个粒子组成的WebGL矩阵展示了Coni WASM的原始威力。但在WebGL流水线中,始终存在一个挥之不去的烦恼:着色器本身。
如果您写过WebGL代码,您一定深有体会。您最终会将顶点着色器和片段着色器写成庞大、混乱的字符串字面量,散布在整个代码库中。您失去了语法高亮、格式化,而且——对于Lisp黑客来说最悲惨的是——您失去了结构化编辑(Paredit/Slurp/Barf)。
今天,我们非常高兴地宣布,我们通过新的 libs/webgl/src/glsl.coni 库征服了最后的这个前沿阵地。
您现在完全可以使用Coni的原生Lisp语法编写您的GLSL着色器了。
defshader 登场
通过利用Coni强大的AST(抽象语法树)和宏系统,我们构建了 defshader。它接受标准的Lisp形式、类型和数学运算,并在它们到达GPU之前,自动将它们转译为严格的GLSL。
看看为我们的Amplifocus粒子引擎编写的这个片段着色器是多么优雅:
(require "libs/webgl/src/glsl.coni" :all)
(defshader fs-src
(precision mediump float)
(varying vec4 v_color)
(defn void main []
;; 原生数学运算与坐标映射!
(set vec2 coord (- gl_PointCoord (vec2 0.5 0.5)))
(set float dist (length coord))
(if (> dist 0.5)
(discard))
;; 使用Lisp S-表达式进行发光(Glow)计算
(set float glow (- 1.0 (* dist 2.0)))
(set vec4 final_color (* v_color glow))
(set gl_FragColor final_color)))
为什么这能颠覆游戏规则?
- 不再有字符串字面量: 您的着色器是一等代码。它们与应用程序的其余部分格式完美统一。
- AST级别的验证: Coni编译器可以在它尝试于浏览器中编译WebGL程序之前,就解析并验证您的着色器结构。
- 结构化编辑: 您可以使用标准的Lisp结构化编辑工具来slurp、barf和操作复杂的GPU数学计算。试着用C风格的GLSL字符串做这些试试!
- 无缝集成: 将其编译成可用的WebGL着色器极其简单,只需调用我们的
core-gl/gl-shader函数即可:(core-gl/gl-shader gl (.-FRAGMENT_SHADER gl) fs-src)。
专为浏览器打造的全栈Lisp
有了这次更新,整个流水线终于完整了。从使用 reframe 的DOM操作,到WebAudio合成,到WASM浮点缓冲,再到现在实际的GPU顶点变换——100%都是Coni。
无需原生JavaScript。无需原生GLSL。只有纯粹的、以惊人速度运行的Lisp。
我们已经将这些全新的Lisp着色器部署到了我们的 deep-focus-webgl 应用中。如果您正在浏览器中构建高性能的交互式体验,是时候试试Coni了!