✦设计雷达
知识地图
2026-09-30 · 今日最炫

Lumin Hands

两只用发光丝线织成的手:WebGPU/TSL 实时 lit tubes,点击冲击波与光晕,视觉冲击极强。

Lumin Hands 截图 打开网站 ↗
大白话拆解

它是什么:两只用发光丝线织成的手:成百上千根 lit GPU tubes 在黑暗里描出轮廓,一点击就炸开冲击波和光晕。

好在哪:一眼就被「电光手」抓住;丝线不是贴图,而是 WebGPU/TSL 实时弯管发光,比静态酷站更像可玩的光装置。

怎么做到的:

  1. 每根丝是一根细管:用 MeshStandardNodeMaterial 的 positionNode 在 GPU 上弯出管壁,再叠自发光。
  2. 大量丝线靠 StorageBuffer + instanceIndex 铺开;关掉 frustumCulled,避免 shader 改位置后被误裁。
  3. UnrealBloomPass 把亮部晕成光晕,SMAA 收细管锯齿;Pointer 点击按教程驱动冲击波。
完整技术拆解

今日拆解 · Lumin Hands

为何选它

8 条里它视觉冲击最强:两只「手」不是建模出来的实体,而是成百上千条发光丝线(lit GPU tubes)织成的轮廓——点击会炸开冲击波与光晕,像在黑暗里用电光描边。Codrops 2026-09-07 刚拆完 WebGPU/TSL 管线,比静态酷站更值得当今日最炫。

实际在源码里找到的技术栈

Three.js r185生产 bundle:const _0="185";data-engine 写入 three.js r${_0} webgpu
WebGPURenderer同 bundle 出现 47+ 次 WebGPURenderer;HTML title 为 Three.js WebGPU
MeshStandardNodeMaterialbundle 字面量 MeshStandardNodeMaterial(2 次);配合 TSL 节点给管子上标准光照感
positionNode / normalNodebundle:this.positionNode=null 与 positionNode!==null 赋值路径;normalNode 亦出现。管子顶点位置由 TSL 节点驱动,而不是静态 mesh 顶点
StorageBuffer / instanceIndexbundle:StorageBuffer、StorageBufferAttribute、StorageBufferNode;instanceIndex(8 次)——大量丝线用 storage + 实例索引在 GPU 上摆开
frustumCulledbundle 24 次。shader 驱动位置时须关掉视锥裁剪,否则管子会被错误剔掉(教程亦强调)
UnrealBloomPassbundle 字面量 UnrealBloomPass(3 次);配合 mrtNode / emissive 路径做发光 bloom
SMAANodebundle 字面量 SMAANode(9 次)——后处理抗锯齿
Tweakpanebundle:Tweakpane / tweakpane——调试面板
ViteHTML:/vite.svg、/assets/index-*.js 模块脚本;典型 Vite 构建产物
Pointer 交互bundle:Pointer 极高密度(200+);click 多次。点击冲击波与光晕的具体数学公式以 Codrops 教程为准(教程细节,非 bundle 字面量公式)
未使用 / 未证实未找到 明确的 motion@x.y.z / GSAP 字面量作为主交互;未找到 Three.js WebGLRenderer 作为主渲染器字面量;bloom 库的 npm semver 未在 bundle 字面量找到 → 只确认类名 UnrealBloomPass

核心效果怎么工作(源码 + 标明推测)

1. WebGPU + Three.js r185 主路径(确认)

页面用 WebGPURenderer 启动;data-engine 写成 three.js r185 webgpu。没有走经典 WebGL 主渲染器。

2. 发光丝线 = 实例化 lit tubes(确认 · TSL)

每条「丝」是一根细管。材质走 MeshStandardNodeMaterial,用 positionNode(以及 normalNode)在 TSL 里算管壁上的点——所以管子可以沿手的轮廓弯曲、发光,而不必为每根丝准备独立静态几何。

3. StorageBuffer + instanceIndex 铺开成百上千根(确认)

丝线数量很大时,位置/参数放进 StorageBuffer,着色器里用 instanceIndex 取自己的那一份。这是「两只手由大量相似丝线组成」的 GPU 侧实现。

4. frustumCulled 必须关掉(确认)

顶点位置由 shader/positionNode 改写后,CPU 侧的包围盒不再可靠;bundle 多次出现 frustumCulled。不关就会出现丝线莫名消失。

5. 发光:UnrealBloomPass + emissive / MRT(确认类名)

UnrealBloomPass 与 mrtNode、大量 emissive 符号同在。管子本身偏自发光,bloom 只把亮部「晕」出去,所以黑暗背景上丝线像霓虹。

6. SMAA 后处理(确认)

SMAANode 做抗锯齿,细管边缘才不会锯成毛刺。

7. 指针与点击冲击波(确认有 Pointer;冲击波细节 = 教程)

Bundle 里 Pointer / click 极多,说明交互主路径是指针。Codrops 教程写明点击会产生冲击波并驱动光晕——具体波前如何改 positionNode / 亮度,以教程为准(标为教程细节)。

8. 伪代码(忠实于 bundle 符号 + 教程结构)

boot:
  renderer = new WebGPURenderer(...)     # Three.js r185
  mat = MeshStandardNodeMaterial({
    positionNode: tubePositionTSL(...),  # 弯曲管子
    normalNode: ...,
    // emissive 路径供 bloom
  })
  strands: StorageBuffer + instanceIndex  # 成百上千根
  mesh.frustumCulled = false

post:
  UnrealBloomPass (emissive / mrtNode)
  SMAANode

pointer:
  Pointer + click → shockwave / glow     # 教程细节
  Tweakpane 调参(debug)

如果我来重做(步骤清单)

  1. Vite + three/webgpu,锁定 Three.js r185,主路径只用 WebGPURenderer。
  2. 先做单根 lit tube:MeshStandardNodeMaterial + positionNode 弯管。
  3. 用 StorageBuffer / instanceIndex 铺成手形轮廓;关掉 frustumCulled。
  4. 加 UnrealBloomPass(emissive)和 SMAANode。
  5. Pointer 点击写冲击波,用 Tweakpane 暴露管径、bloom、波强度。
  6. 用较新的 Chrome / Edge 验证 WebGPU;对照 Codrops 2026-09-07 教程补交互手感。
小白课

零基础也能看懂。先认识这件作品用到的技术,再学一个知识点。

1技术栈小白版

只列拆解里在源码中确认过的技术。点开看它在这件作品里做了什么。

Three.js r185网页里的「3D 工具箱」:帮你摆物体、管相机、跟显卡说话。

在这件作品里整双手的丝线场景、相机和渲染管线都跑在 Three.js r185 上。

怎么认出来浏览器里能实时转、点、发光的 3D,而不是一段固定视频。

WebGPURenderer新一代「显卡直通车」:更接近现代显卡的工作方式,适合堆很多发光细管。

在这件作品里主渲染器是 WebGPURenderer,所以成百上千根 lit tubes 还能保持流畅。

怎么认出来用较新的 Chrome / Edge 打开更稳;页面标题也写着 Three.js WebGPU。

MeshStandardNodeMaterial一张「带标准光照感」的材料卡片,颜色和形状还可以用节点图临时算。

在这件作品里每根发光丝线的管壁材质走它;再配合 positionNode 把管子弯成手的轮廓。

怎么认出来丝线看起来有体积和高光,不像平面画上去的线。

positionNode告诉显卡:「这个点不要用模型里写死的位置,按我这套公式现算。」

在这件作品里管子顶点由 positionNode 驱动,所以丝线能弯、能被冲击波推开。

怎么认出来点击后丝线会像被风吹开,而不是整只手模型硬挪位置。

StorageBuffer / instanceIndex一块给成千上万个「分身」读自己参数的共享记事本;instanceIndex 是每个分身的编号。

在这件作品里大量丝线的数据放进 StorageBuffer,着色器用 instanceIndex 取出自己那一根。

怎么认出来你看到的是「密密麻麻很多根相似的线」,而不是一只平滑的手套模型。

UnrealBloomPass专门把画面里「够亮的部分」晕成光晕的后期滤镜。

在这件作品里管子自发光之后,UnrealBloomPass 把亮部扩散成霓虹光晕。

怎么认出来黑暗背景上,手指边缘会冒一圈柔和的光,而不是死硬的亮线。

SMAANode给细边「去锯齿」的后期步骤,让斜线和弯管不那么毛刺。

在这件作品里细管很多,SMAANode 负责把边缘收干净。

怎么认出来丝线边缘比较顺,不像老游戏里那种明显台阶锯齿。

2今日知识点

设计理论 · 第 2 课

格式塔(上):接近与相似

人眼不是一个像素一个像素地「数」东西,而是会自动分组。格式塔心理学里最常用的两条:接近(离得近的算一组)和相似(长得像的算一组)。

Lumin Hands 没有建模一只光滑的手 mesh,而是铺了成百上千根又细又亮、彼此靠近的丝线。因为它们相似(都是发光细管)又接近(挤在手指轮廓里),你的大脑直接读成「两只手」——这就是接近 + 相似在干活。

设计上你可以故意用这两条:要让人看出「这是一组」,就让元素长得像、靠得近;要拆开两组,就拉开距离或改掉颜色/形状。

反过来:如果丝线颜色乱、间距忽大忽小,手的完形就会散掉——技术再炫,分组一乱,认知就跟不上。

今日口诀:近的像的 = 一组。先问「我有没有让该成组的东西够近、够像?」再谈特效。

它从哪里来

格式塔(Gestalt)心理学兴起于 20 世纪初的德国,核心主张是「整体不等于部分之和」——人先看到结构,再看到零件。

马克斯·韦特海默(Max Wertheimer)等人整理出接近、相似、闭合、连续等组织律,后来被平面设计、UI、信息图广泛借用。

在创意前端和数据可视化里,这两条几乎天天用:散点何时成「簇」、导航何时成「一组按钮」,靠的都是接近与相似。

Lumin Hands 是 contempor 的 WebGPU 作品,但观众秒懂「这是手」,靠的仍是一百年前就被写清楚的视觉组织律。

经典参考

怎么看 / 怎么练 · 约 8 分钟
  1. 打开 Lumin Hands,盯住 3 秒:你是先看到「很多线」,还是直接看到「手」?把第一印象写下一句。
  2. 想象把丝线颜色改成红绿蓝随机、间距拉得忽大忽小——手还在吗?用接近/相似各写一条「为什么会散」。
  3. 看自己手机桌面或常用 App 底栏:哪一组图标是靠「接近」成组的?哪一组是靠「相似」(同色/同形)?各举一例。

小词典

格式塔(Gestalt)
强调「整体结构」的心理学传统;设计里常指那些让人自动把元素看成一组的规律。
接近律(Proximity)
空间上离得近的东西,更容易被看成同一组。
相似律(Similarity)
颜色、形状、方向等属性相近的东西,更容易被看成同一组。
完形 / 组织
大脑把零散刺激整理成有意义形状的过程;Lumin Hands 里就是把丝线织成「手」。

3知识地图进度

设计理论第 2 课 / 共 14 课
这条线已学 3 课全部已学 10 / 89
下一课建议理论 第 3 课 · 格式塔(下):闭合、连续、图形与背景 打开知识地图 ›
当天另外 7 个
小游戏
Caustic Volume
电影级体积焦散与水下光纹,Lite/Full 两档,社交上近一周最炸的着色器秀。
小游戏
Geometry Painter
在曲面上「画」晶体、熔岩、极光与荧光礁——程序几何玩具,WebGPU/TSL。
小游戏
Jelly Baby
软萌果冻小人:蹦跳拉伸的物理手感,治愈向 web-game。
小游戏
Magical Canopy
WebGPU/TSL 体素树冠 raymarch:叶层随风、指针带光晕,体积感像电影。
小游戏
Rainy Worlds
六个超写实雨天世界可走进:森林/海角/夜驶,氛围碾压。
小游戏
Theatre (Opus 5.5)
用 Claude Opus 5.5 生成的 EVA 风 Three.js/WebGL 剧场场景,AI 造站热潮样本。
小游戏
Three.js Fish
WebGPU/Three.js 写实鱼群:自然游动的水下学校,官方账号都在推。

设计雷达 · 每天 8 个值得看的网站、App UI 和网页小游戏