<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title>Shaders on NicoLabs</title>
		<link>http://blog.hellonico.info/zh/tags/shaders/</link>
		<description>Recent content in Shaders on NicoLabs</description>
		<generator>Hugo</generator>
		<language>zh</language>
		
		
		
		
			<lastBuildDate>Sun, 28 Jun 2026 07:30:00 +0900</lastBuildDate>
		
			<atom:link href="http://blog.hellonico.info/zh/tags/shaders/index.xml" rel="self" type="application/rss+xml" />
			<item>
				<title>用纯Coni Lisp编写WebGL着色器！</title>
				<link>http://blog.hellonico.info/zh/posts/coni/coni-webgl-shaders/</link>
				<pubDate>Sun, 28 Jun 2026 07:30:00 +0900</pubDate>
				<guid>http://blog.hellonico.info/zh/posts/coni/coni-webgl-shaders/</guid>
				<description>&lt;p&gt;在上一篇文章中，我们通过编排一个由80,000个粒子组成的WebGL矩阵展示了Coni WASM的原始威力。但在WebGL流水线中，始终存在一个挥之不去的烦恼：&lt;strong&gt;着色器本身&lt;/strong&gt;。&lt;/p&gt;&#xA;&lt;p&gt;如果您写过WebGL代码，您一定深有体会。您最终会将顶点着色器和片段着色器写成庞大、混乱的字符串字面量，散布在整个代码库中。您失去了语法高亮、格式化，而且——对于Lisp黑客来说最悲惨的是——您失去了结构化编辑（Paredit/Slurp/Barf）。&lt;/p&gt;&#xA;&lt;p&gt;今天，我们非常高兴地宣布，我们通过新的 &lt;code&gt;libs/webgl/src/glsl.coni&lt;/code&gt; 库征服了最后的这个前沿阵地。&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;您现在完全可以使用Coni的原生Lisp语法编写您的GLSL着色器了。&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;h3 id=&#34;defshader-登场&#34;&gt;&lt;code&gt;defshader&lt;/code&gt; 登场&lt;/h3&gt;&#xA;&lt;p&gt;通过利用Coni强大的AST（抽象语法树）和宏系统，我们构建了 &lt;code&gt;defshader&lt;/code&gt;。它接受标准的Lisp形式、类型和数学运算，并在它们到达GPU之前，自动将它们转译为严格的GLSL。&lt;/p&gt;&#xA;&lt;p&gt;看看为我们的Amplifocus粒子引擎编写的这个片段着色器是多么优雅：&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;require&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;libs/webgl/src/glsl.coni&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;:all&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;defshader&lt;/span&gt; fs-src&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#a6e22e&#34;&gt;precision&lt;/span&gt; mediump float)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#a6e22e&#34;&gt;varying&lt;/span&gt; vec4 v_color)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#66d9ef&#34;&gt;defn &lt;/span&gt;void main []&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;;; 原生数学运算与坐标映射！&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (set vec2 coord (- gl_PointCoord (&lt;span style=&#34;color:#a6e22e&#34;&gt;vec2&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0.5&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0.5&lt;/span&gt;)))&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (set float dist (&lt;span style=&#34;color:#a6e22e&#34;&gt;length&lt;/span&gt; coord))&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#66d9ef&#34;&gt;if &lt;/span&gt;(&amp;gt; dist &lt;span style=&#34;color:#ae81ff&#34;&gt;0.5&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      (&lt;span style=&#34;color:#a6e22e&#34;&gt;discard&lt;/span&gt;))&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;;; 使用Lisp S-表达式进行发光（Glow）计算&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (set float glow (- &lt;span style=&#34;color:#ae81ff&#34;&gt;1.0&lt;/span&gt; (* dist &lt;span style=&#34;color:#ae81ff&#34;&gt;2.0&lt;/span&gt;)))&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (set vec4 final_color (* v_color glow))&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (set gl_FragColor final_color)))&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;为什么这能颠覆游戏规则&#34;&gt;为什么这能颠覆游戏规则？&lt;/h3&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&lt;strong&gt;不再有字符串字面量:&lt;/strong&gt; 您的着色器是一等代码。它们与应用程序的其余部分格式完美统一。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;AST级别的验证:&lt;/strong&gt; Coni编译器可以在它尝试于浏览器中编译WebGL程序之前，就解析并验证您的着色器结构。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;结构化编辑:&lt;/strong&gt; 您可以使用标准的Lisp结构化编辑工具来slurp、barf和操作复杂的GPU数学计算。试着用C风格的GLSL字符串做这些试试！&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;无缝集成:&lt;/strong&gt; 将其编译成可用的WebGL着色器极其简单，只需调用我们的 &lt;code&gt;core-gl/gl-shader&lt;/code&gt; 函数即可：&lt;code&gt;(core-gl/gl-shader gl (.-FRAGMENT_SHADER gl) fs-src)&lt;/code&gt;。&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h3 id=&#34;专为浏览器打造的全栈lisp&#34;&gt;专为浏览器打造的全栈Lisp&lt;/h3&gt;&#xA;&lt;p&gt;有了这次更新，整个流水线终于完整了。从使用 &lt;code&gt;reframe&lt;/code&gt; 的DOM操作，到WebAudio合成，到WASM浮点缓冲，再到现在实际的GPU顶点变换——100%都是Coni。&lt;/p&gt;</description>
			</item>
	</channel>
</rss>
