<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title>Webgl on NicoLabs</title>
		<link>http://blog.hellonico.info/zh/tags/webgl/</link>
		<description>Recent content in Webgl on NicoLabs</description>
		<generator>Hugo</generator>
		<language>zh</language>
		
		
		
		
			<lastBuildDate>Thu, 02 Jul 2026 12:00:00 +0900</lastBuildDate>
		
			<atom:link href="http://blog.hellonico.info/zh/tags/webgl/index.xml" rel="self" type="application/rss+xml" />
			<item>
				<title>Coni中的程序化音频与WebGL WebAssembly体验</title>
				<link>http://blog.hellonico.info/zh/posts/coni/procedural-audiovisual-wasm/</link>
				<pubDate>Thu, 02 Jul 2026 12:00:00 +0900</pubDate>
				<guid>http://blog.hellonico.info/zh/posts/coni/procedural-audiovisual-wasm/</guid>
				<description>&lt;p&gt;仅在过去的24小时内，我们就突破了&lt;strong&gt;Coni WebAssembly&lt;/strong&gt;生态系统的边界，制作了整套程序化视听网络体验。通过将Coni宏系统与原始WebGL及WebAudio API相结合，我们成功地在浏览器中原生搭建、编译和部署了复杂的图形和音乐系统，并且绝对零外部资产依赖。&lt;/p&gt;&#xA;&lt;p&gt;让我们来看看我们构建的这五个新应用。您可以在&lt;a href=&#34;https://coni-lang.org/wasm-apps/&#34; target=&#34;_blank&#34; rel=&#34;noopener noreffer &#34;&gt;Coni WASM Gallery&lt;/a&gt;的浏览器中原生体验它们。&lt;/p&gt;&#xA;&lt;h3 id=&#34;1-极简techno视觉化工具-minimal-techno-visualizer&#34;&gt;1. 极简Techno视觉化工具 (Minimal Techno Visualizer)&lt;/h3&gt;&#xA;&lt;p&gt;&lt;strong&gt;主题:&lt;/strong&gt; 黑暗、充满驱动力的算法俱乐部能量。&#xA;&lt;em&gt;链接:&lt;/em&gt; &lt;a href=&#34;https://coni-lang.org/wasm-apps/apps/minimal-techno/&#34; target=&#34;_blank&#34; rel=&#34;noopener noreffer &#34;&gt;Minimal Techno App&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt;我们想要证明Coni能够编排实时的程序化音乐生成，并将其与繁重的3D几何渲染完美同步。&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;音频引擎:&lt;/strong&gt; 定制的140 BPM时间线引擎在16分音符的弱拍上触发模拟风格的锯齿波低音线，搭配808风格的合成底鼓，并在高潮段（Drop）引入清脆的基于噪声的军鼓/拍手声。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;WebGL细节:&lt;/strong&gt; 我们映射了5,000个在16小节“Breakdown”期间反转重力的下落雨粒，以及一个致密脉动的3D几何核心，它在每次底鼓敲击时猛烈绽放，并根据音序器状态从冷青色转变为火橙色。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h3 id=&#34;2-999hz-神圣无限-divine-infinity-999hz&#34;&gt;2. 999Hz 神圣无限 (Divine Infinity 999Hz)&lt;/h3&gt;&#xA;&lt;p&gt;&lt;strong&gt;主题:&lt;/strong&gt; 空灵的数学疗愈。&#xA;&lt;em&gt;链接:&lt;/em&gt; &lt;a href=&#34;https://coni-lang.org/wasm-apps/apps/infinity-999hz/&#34; target=&#34;_blank&#34; rel=&#34;noopener noreffer &#34;&gt;Divine Infinity 999Hz&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt;这个应用以神圣频率疗愈的概念为核心，是纯粹数学与环境音频的完美结合。&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;音频引擎:&lt;/strong&gt; 它生成999Hz的“天使频率”正弦波，并辅以微妙的8Hz Theta双耳节拍，以诱导深度放松。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;WebGL细节:&lt;/strong&gt; 我们在GLSL顶点着色器中使用纯三角函数，将500,000个粒子映射到“伯努利双纽线”（无限大符号）上。它在3D空间中完美渲染，带有微妙的环境光晕和基于深度的不透明度渐隐。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h3 id=&#34;3-清除脑雾-40hz-clear-brain-fog-40hz&#34;&gt;3. 清除脑雾 40Hz (Clear Brain Fog 40Hz)&lt;/h3&gt;&#xA;&lt;p&gt;&lt;strong&gt;主题:&lt;/strong&gt; 几何的清晰与专注。&#xA;&lt;em&gt;链接:&lt;/em&gt; &lt;a href=&#34;https://coni-lang.org/wasm-apps/apps/brain-fog-40hz/&#34; target=&#34;_blank&#34; rel=&#34;noopener noreffer &#34;&gt;Clear Brain Fog 40Hz&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt;旨在驱散精神杂念，此应用使用令人着迷的几何图形搭配接地频率。&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;音频引擎:&lt;/strong&gt; 通过微调两个振荡器（左耳432Hz，右耳472Hz）创建的纯40Hz双耳节拍。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;WebGL细节:&lt;/strong&gt; 我们在顶点着色器中编程了一个拥有5片旋转花瓣的3D繁花曲线。复杂的重叠曲线产生了一种不断向前运动的错觉，而摄像机实际上根本没有移动，使眼睛陷入一种心流状态。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h3 id=&#34;4-webgl呼吸引导应用-webgl-guided-breathing-app&#34;&gt;4. WebGL呼吸引导应用 (WebGL Guided Breathing App)&lt;/h3&gt;&#xA;&lt;p&gt;&lt;strong&gt;主题:&lt;/strong&gt; 控制下的节奏感冥想。&#xA;&lt;em&gt;链接:&lt;/em&gt; &lt;a href=&#34;https://coni-lang.org/wasm-apps/apps/breathing-app/&#34; target=&#34;_blank&#34; rel=&#34;noopener noreffer &#34;&gt;Breathing App&lt;/a&gt;&lt;/p&gt;</description>
			</item>
			<item>
				<title>WebGL呼吸引导: 6-2-6的交互式体验</title>
				<link>http://blog.hellonico.info/zh/posts/coni/breathing-app-webgl/</link>
				<pubDate>Mon, 29 Jun 2026 23:35:00 +0900</pubDate>
				<guid>http://blog.hellonico.info/zh/posts/coni/breathing-app-webgl/</guid>
				<description>&lt;p&gt;在当今快节奏的数字世界中，心理健康和专注力至关重要。继我们的脑波同步应用取得成功后，我们决定解决幸福感的另一个方面：&lt;strong&gt;有意识的呼吸&lt;/strong&gt;。&lt;/p&gt;&#xA;&lt;p&gt;我们很高兴揭晓我们最新的Coni WASM应用程序：&lt;strong&gt;WebGL呼吸应用 (WebGL Breathing App)&lt;/strong&gt;。这是一个从零开始构建的视听体验，旨在引导您完成一段平静的6-2-6呼吸练习（吸气6秒，屏息2秒，呼气6秒）。&lt;/p&gt;&#xA;&lt;h3 id=&#34;打造栩栩如生的ui&#34;&gt;打造栩栩如生的UI&lt;/h3&gt;&#xA;&lt;p&gt;与仅仅显示一个不断变大圆圈的传统呼吸计时器不同，我们希望构建一些让人感觉有生命力的东西。我们设计了一个交互式菜单，您可以在其中设置您的&lt;strong&gt;心境 (Mood)&lt;/strong&gt;——从&lt;em&gt;平静 Calm&lt;/em&gt;（青色）、&lt;em&gt;温暖 Warm&lt;/em&gt;（橙色）或&lt;em&gt;专注 Focus&lt;/em&gt;（紫色）中选择。&lt;/p&gt;&#xA;&lt;p&gt;&lt;img&#xA;        class=&#34;lazyload&#34;&#xA;        src=&#34;http://blog.hellonico.info/svg/loading.min.svg&#34;&#xA;        data-src=&#34;../breathe_in_01.png&#34;&#xA;        data-srcset=&#34;../breathe_in_01.png, ../breathe_in_01.png 1.5x, ../breathe_in_01.png 2x&#34;&#xA;        data-sizes=&#34;auto&#34;&#xA;        alt=&#34;../breathe_in_01.png&#34;&#xA;        title=&#34;Breathing App Interface - Calm&#34; /&gt;&lt;/p&gt;&#xA;&lt;p&gt;当您开始练习时，背景环境噪音和程序生成的铃声开始播放。这些声音完全由Web Audio API驱动，并由原生Coni函数无缝调度。通过将逻辑与标准JS运行时的卡顿隔离开来，音频保持完美的连贯性且没有抖动。&lt;/p&gt;&#xA;&lt;h3 id=&#34;gpu的力量&#34;&gt;GPU的力量&lt;/h3&gt;&#xA;&lt;p&gt;在底层，应用程序生成一个由&lt;strong&gt;30,000个几何粒子&lt;/strong&gt;组成的簇，这些粒子在WebAssembly中原生计算和缓存。我们将这些点连同您选择的心境颜色以及一个连续的 &lt;code&gt;u_breath_factor&lt;/code&gt; 传递给WebGL着色器。&lt;/p&gt;&#xA;&lt;p&gt;当您吸气时，球体膨胀，其半径动态缩放，同时其顶点通过直接在顶点着色器中应用的三角正弦和余弦操作而轻柔起伏。颜色强度也会增加，模拟能量的扩张。&lt;/p&gt;&#xA;&lt;p&gt;当您呼气时，球体收缩成一个紧凑的核心。&lt;/p&gt;&#xA;&lt;p&gt;&lt;img&#xA;        class=&#34;lazyload&#34;&#xA;        src=&#34;http://blog.hellonico.info/svg/loading.min.svg&#34;&#xA;        data-src=&#34;../breathe_in_02.png&#34;&#xA;        data-srcset=&#34;../breathe_in_02.png, ../breathe_in_02.png 1.5x, ../breathe_in_02.png 2x&#34;&#xA;        data-sizes=&#34;auto&#34;&#xA;        alt=&#34;../breathe_in_02.png&#34;&#xA;        title=&#34;Breathing App WebGL Particle Sphere&#34; /&gt;&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:#75715e&#34;&gt;;; 我们完全在WASM中计算阶段&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;update-phase [t phase-text]&#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;let &lt;/span&gt;[cycle-time (&lt;span style=&#34;color:#a6e22e&#34;&gt;fmod&lt;/span&gt; t &lt;span style=&#34;color:#ae81ff&#34;&gt;14000.0&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        inhale-time &lt;span style=&#34;color:#ae81ff&#34;&gt;6000.0&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        hold-time &lt;span style=&#34;color:#ae81ff&#34;&gt;2000.0&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        exhale-time &lt;span style=&#34;color:#ae81ff&#34;&gt;6000.0&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;lt; cycle-time inhale-time)&#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;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;通过将视觉变换卸载到GPU，并在WASM中原生保持严格的状态同步，我们实现了如丝般顺滑的60fps体验，感觉非常自然，而不是机械生硬的。&lt;/p&gt;</description>
			</item>
			<item>
				<title>针对Coni原生Float32数组的硬核混沌测试</title>
				<link>http://blog.hellonico.info/zh/posts/coni/float32-chaos-testing/</link>
				<pubDate>Sun, 28 Jun 2026 11:30:00 +0900</pubDate>
				<guid>http://blog.hellonico.info/zh/posts/coni/float32-chaos-testing/</guid>
				<description>&lt;p&gt;当您在浏览器中构建高性能应用程序时，JavaScript通用的 &lt;code&gt;Number&lt;/code&gt; 类型通常是不够的。您需要原始的、连续的内存数组。在Coni WASM中，我们在计算最密集的应用程序上严重依赖原生的WebAssembly &lt;code&gt;float32&lt;/code&gt; 数组。&lt;/p&gt;&#xA;&lt;h3 id=&#34;float32在coni中到底用在哪里&#34;&gt;Float32在Coni中到底用在哪里？&lt;/h3&gt;&#xA;&lt;p&gt;原生 &lt;code&gt;float32&lt;/code&gt; 数组（&lt;code&gt;make-float32-array&lt;/code&gt;、&lt;code&gt;f32-set!&lt;/code&gt;、&lt;code&gt;f32-get&lt;/code&gt;）是Coni性能层的绝对主干。您会发现它们驱动着：&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&lt;strong&gt;WebGL几何体:&lt;/strong&gt; 在我们的 &lt;a href=&#34;https://coni-lang.org/wasm-apps/apps/deep-focus-webgl/&#34; target=&#34;_blank&#34; rel=&#34;noopener noreffer &#34;&gt;&lt;code&gt;deep-focus-webgl&lt;/code&gt;&lt;/a&gt; 应用中，我们使用 &lt;code&gt;float32&lt;/code&gt; 数组在原生层面通过数学方式塑造一个拥有80,000个顶点的大脑矩阵（240,000个浮点数！），然后通过 &lt;code&gt;js/float32-buffer&lt;/code&gt; 将其一次性发送给GPU。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;游戏引擎粒子系统:&lt;/strong&gt; 对于像 &lt;code&gt;flappy-bird&lt;/code&gt; 或 &lt;code&gt;neon-boids&lt;/code&gt; 这样的游戏，并行的 &lt;code&gt;float32&lt;/code&gt; 数组无需垃圾回收的停顿，即可跟踪数以千计的X/Y坐标、速度和生命周期。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;原始DSP音频:&lt;/strong&gt; 我们的 &lt;code&gt;sound-nodes&lt;/code&gt; 合成器在将复杂的脉冲响应和噪声波形映射到WebAudio通道之前，使用 &lt;code&gt;float32&lt;/code&gt; 数组在原生层面计算它们。&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h3 id=&#34;错误所在类型强制转换与-f64reinterpret_i64&#34;&gt;错误所在：类型强制转换与 &lt;code&gt;f64.reinterpret_i64&lt;/code&gt;&lt;/h3&gt;&#xA;&lt;p&gt;因为这些数组极其关键，它们中的任何错误都将是灾难性的。最近，我们发现了一个问题：将一个精确的整数（如 &lt;code&gt;150&lt;/code&gt;）传入 &lt;code&gt;f32-set!&lt;/code&gt; 时，会莫名其妙地产生 &lt;code&gt;0.0&lt;/code&gt;。&lt;/p&gt;&#xA;&lt;p&gt;到底发生了什么？在较早版本的WASM编译器中，将整数传递给浮点数setter会导致编译器错误地使用 &lt;code&gt;f64.reinterpret_i64&lt;/code&gt; 来解释这些位，从而完全扰乱了底层的值。&lt;/p&gt;&#xA;&lt;h3 id=&#34;解决方案float32混沌测试-chaos-testing&#34;&gt;解决方案：Float32混沌测试 (Chaos Testing)&lt;/h3&gt;&#xA;&lt;p&gt;我们修补了编译器，以便在插入内存之前将整数正确地强制转换为浮点数，但我们需要一个保证，确保它永远不会再次退化。于是，&lt;strong&gt;混沌测试&lt;/strong&gt;登场了。&lt;/p&gt;&#xA;&lt;p&gt;在新的 &lt;code&gt;float32_coercion_test.coni&lt;/code&gt; 测试套件中，我们构建了一个硬核的混沌测试。我们不是仅仅测试几个顺利通过的数字，而是分配了一个巨大的数组，并用确定性的、伪随机的循环来猛烈敲击它。&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;deftest&lt;/span&gt; test-f32-chaos&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;针对float32数组边界和类型转换的硬核混沌测试。&amp;#34;&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;let &lt;/span&gt;[size &lt;span style=&#34;color:#ae81ff&#34;&gt;1000&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        arr (&lt;span style=&#34;color:#a6e22e&#34;&gt;make-float32-array&lt;/span&gt; size)]&#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;loop &lt;/span&gt;[i &lt;span style=&#34;color:#ae81ff&#34;&gt;0&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;lt; i size)&#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;let &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;;; 混合生成极端边缘用例：&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          val (&lt;span style=&#34;color:#66d9ef&#34;&gt;if &lt;/span&gt;(= (&lt;span style=&#34;color:#a6e22e&#34;&gt;mod&lt;/span&gt; i &lt;span style=&#34;color:#ae81ff&#34;&gt;4&lt;/span&gt;) &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;) (- &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt; i)                   &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;                (&lt;span style=&#34;color:#66d9ef&#34;&gt;if &lt;/span&gt;(= (&lt;span style=&#34;color:#a6e22e&#34;&gt;mod&lt;/span&gt; i &lt;span style=&#34;color:#ae81ff&#34;&gt;4&lt;/span&gt;) &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;) (* i &lt;span style=&#34;color:#ae81ff&#34;&gt;10000&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;                  (&lt;span style=&#34;color:#66d9ef&#34;&gt;if &lt;/span&gt;(= (&lt;span style=&#34;color:#a6e22e&#34;&gt;mod&lt;/span&gt; i &lt;span style=&#34;color:#ae81ff&#34;&gt;4&lt;/span&gt;) &lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;) (+ i &lt;span style=&#34;color:#ae81ff&#34;&gt;0.5&lt;/span&gt;)             &lt;span style=&#34;color:#75715e&#34;&gt;;; 精确的float32小数&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:#ae81ff&#34;&gt;0&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;        ]&#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;f32-set!&lt;/span&gt; arr i val)&#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;recur&lt;/span&gt; (+ i &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;)))&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        nil))&#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;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;通过故意将极端正整数、负边界值、纯零和带有小数的浮点数这种残酷的混合物向 &lt;code&gt;f32-set!&lt;/code&gt; 函数抛出1,000次，我们保证了能避免WASM陷阱（traps），并且类型强制转换变得坚不可摧。&lt;/p&gt;</description>
			</item>
			<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>
			<item>
				<title>在Coni WASM中构建40Hz认知专注应用</title>
				<link>http://blog.hellonico.info/zh/posts/coni/brain-waves-wasm/</link>
				<pubDate>Sun, 28 Jun 2026 07:30:00 +0900</pubDate>
				<guid>http://blog.hellonico.info/zh/posts/coni/brain-waves-wasm/</guid>
				<description>&lt;p&gt;浏览器中的WebAssembly一直承诺提供令人难以置信的性能，但将其与WebAudio和WebGL等Web API顺畅连接有时感觉像是在解谜。今天，我们非常高兴地展示Coni生态系统如何通过引入两个专为认知专注而设计的全新Web应用来优雅地解决这个问题。&lt;/p&gt;&#xA;&lt;p&gt;这两个应用程序使用双耳节拍生成&lt;strong&gt;40Hz伽马频率&lt;/strong&gt;——一种与深度专注、记忆唤起和认知提升相关的特定脑波频率。但真正的魔力在底层：它们完全是用&lt;strong&gt;Coni WASM&lt;/strong&gt;编写的。&lt;/p&gt;&#xA;&lt;h3 id=&#34;40hz伽马波的科学&#34;&gt;40Hz伽马波的科学&lt;/h3&gt;&#xA;&lt;p&gt;在深入探讨技术之前，为什么选择40Hz？伽马波是脑波频率中最快的。研究表明，当大脑在40Hz范围内运作时，它与敏锐的感知、问题解决能力和巅峰的注意力相关联。&lt;/p&gt;&#xA;&lt;p&gt;通过在左耳播放60Hz的正弦波，在右耳播放100Hz的正弦波，大脑会感知到恰好40Hz的频率差“节拍”。这个过程被称为脑波同步（brainwave entrainment），它会温和地将您的认知状态推入伽马频率。&lt;/p&gt;&#xA;&lt;p&gt;为了展示Coni架构在提供这种体验方面的灵活性，我们构建了该应用的两个截然不同的版本：&lt;/p&gt;&#xA;&lt;h3 id=&#34;1-canvas版本-deep-focus-40hz&#34;&gt;1. Canvas版本: &lt;a href=&#34;https://coni-lang.org/wasm-apps/apps/deep-focus-40hz/&#34; target=&#34;_blank&#34; rel=&#34;noopener noreffer &#34;&gt;&lt;code&gt;deep-focus-40hz&lt;/code&gt;&lt;/a&gt;&lt;/h3&gt;&#xA;&lt;p&gt;&lt;img&#xA;        class=&#34;lazyload&#34;&#xA;        src=&#34;http://blog.hellonico.info/svg/loading.min.svg&#34;&#xA;        data-src=&#34;../deepfocus.png&#34;&#xA;        data-srcset=&#34;../deepfocus.png, ../deepfocus.png 1.5x, ../deepfocus.png 2x&#34;&#xA;        data-sizes=&#34;auto&#34;&#xA;        alt=&#34;../deepfocus.png&#34;&#xA;        title=&#34;Deep Focus 40Hz Screenshot&#34; /&gt;&lt;/p&gt;&#xA;&lt;p&gt;我们的第一个应用程序依赖于传统的2D Canvas和DOM API。我们利用自定义的&lt;code&gt;reframe_wasm&lt;/code&gt;库，直接通过WebAssembly以Hiccup风格的DOM生成来处理UI状态和渲染。&lt;/p&gt;&#xA;&lt;p&gt;音频引擎完全以接近原生的速度细致地管理振荡器。我们甚至构建了一个自动生成铃声系统，它可以实时调制包络——完全避免了JS的开销：&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:#75715e&#34;&gt;;; 无需JS绑定的富有表现力的WebAudio包络！&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(doto (&lt;span style=&#34;color:#a6e22e&#34;&gt;.-gain&lt;/span&gt; gain)&#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;.linearRampToValueAtTime&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0.15&lt;/span&gt; (+ now &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;  (&lt;span style=&#34;color:#a6e22e&#34;&gt;.exponentialRampToValueAtTime&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0.001&lt;/span&gt; (+ now &lt;span style=&#34;color:#ae81ff&#34;&gt;8.0&lt;/span&gt;)))&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这是在纯Coni中构建一个响应式、高性能音频引擎的完美例子。&lt;/p&gt;&#xA;&lt;h3 id=&#34;2-webgl性能怪兽-deep-focus-webgl&#34;&gt;2. WebGL性能怪兽: &lt;a href=&#34;https://coni-lang.org/wasm-apps/apps/deep-focus-webgl/&#34; target=&#34;_blank&#34; rel=&#34;noopener noreffer &#34;&gt;&lt;code&gt;deep-focus-webgl&lt;/code&gt;&lt;/a&gt;&lt;/h3&gt;&#xA;&lt;p&gt;&lt;img&#xA;        class=&#34;lazyload&#34;&#xA;        src=&#34;http://blog.hellonico.info/svg/loading.min.svg&#34;&#xA;        data-src=&#34;../deepfocus-webgl.png&#34;&#xA;        data-srcset=&#34;../deepfocus-webgl.png, ../deepfocus-webgl.png 1.5x, ../deepfocus-webgl.png 2x&#34;&#xA;        data-sizes=&#34;auto&#34;&#xA;        alt=&#34;../deepfocus-webgl.png&#34;&#xA;        title=&#34;Deep Focus WebGL Screenshot&#34; /&gt;&lt;/p&gt;&#xA;&lt;p&gt;虽然Canvas版本很棒，但我们想看看我们能将Coni的原生处理能力推到多远。于是&lt;code&gt;deep-focus-webgl&lt;/code&gt;（内部代号为Amplifocus）诞生了。&lt;/p&gt;&#xA;&lt;p&gt;这个版本不再依赖2D Canvas，而是使用纯WebGL渲染一个由&lt;strong&gt;80,000个粒子组成的脑矩阵&lt;/strong&gt;。&#xA;是什么让这真正令人兴奋？&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;100%纯Coni:&lt;/strong&gt; GPU加速的顶点变换和海量粒子数组逻辑都在Coni WASM中原生处理。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;零JS数学开销:&lt;/strong&gt; 通过使用Coni的数学库（&lt;code&gt;libs/math&lt;/code&gt;），我们计算了数万个顶点的复杂三角函数变换，而无需跨越昂贵的JS-WASM桥梁。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;下面看看我们在原生浮点缓冲中塑造3D几何体并将其发送给GPU是多么毫不费力：&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:#75715e&#34;&gt;;; 在WASM内存中处理8万个顶点，一次性发送给GPU！&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;f32-set!&lt;/span&gt; *base-points* idx final-x)&#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;f32-set!&lt;/span&gt; *base-points* (+ idx &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;) final-sy)&#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;f32-set!&lt;/span&gt; *base-points* (+ idx &lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;) (* z &lt;span style=&#34;color:#ae81ff&#34;&gt;1.1&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;;; 一次性上传静态几何体&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;gl/upload-static-data&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;@&lt;/span&gt;*gl-state* (&lt;span style=&#34;color:#a6e22e&#34;&gt;js/float32-buffer&lt;/span&gt; *base-points*))&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;我们只需分配一次浮点数组，原生处理几何数据，然后通过单一缓冲操作将其瞬间送至GPU。&lt;/p&gt;</description>
			</item>
	</channel>
</rss>
