mcpField
T
threejs-impl-webgpu

threejs-impl-webgpu

github.com/impertio-studio开发23134 次安装30 周前更新
代码仓库

关于 threejs-impl-webgpu

threejs-impl-webgpu 是面向 Three.js 开发者的 WebGPU 实现参考技能,介绍 WebGPURenderer、TSL、节点材质、计算着色器与后期处理。内容注明相关 API 仍处于实验阶段。

主要功能

  1. 01初始化 WebGPURenderer 并检测支持情况
  2. 02使用 TSL 构建节点材质
  3. 03通过计算着色器执行 GPU 计算
  4. 04配置 WebGPU 后期处理
  5. 05说明从 WebGL 迁移的步骤
  6. 06提供 WebGL 回退建议

适用场景

  1. 01为 Three.js 场景配置 WebGPU 渲染
  2. 02使用 TSL 编写材质和着色逻辑
  3. 03将 WebGL 渲染流程迁移到 WebGPU

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/impertio-studio/three.js-claude-skill-package --skill threejs-impl-webgpu

安装后在 Claude Code 中输入/threejs-impl-webgpu确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

.gitkeep
references/
anti-patterns.md
examples.md
methods.md

详细介绍

threejs-impl-webgpu

实验性 — WebGPU 渲染器和 TSL 正在积极开发中。 API 接口可能会随 Three.js 版本更新而变化。请固定 Three.js 版本。

快速参考

WebGPURenderer 设置
import * as THREE from 'three/webgpu';

const renderer = new THREE.WebGPURenderer({ antialias: true });
await renderer.init(); // MUST await before first render
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setAnimationLoop(animate);
document.body.appendChild(renderer.domElement);

务必在首次调用 renderer.render() 前调用 await renderer.init()。 务必使用 renderer.setAnimationLoop(callback),而不是 requestAnimationFrame。 切勿在 init() 完成前调用 renderer.render() — 这会导致运行时错误。

浏览器支持
浏览器版本状态
Chrome113+完全支持
Edge113+完全支持
Safari18+支持
Firefox实验性需启用标志(dom.webgpu.enabled)
功能检测与回退
import { WebGPU } from 'three/webgpu';

if (WebGPU.isAvailable()) {
  const renderer = new THREE.WebGPURenderer({ antialias: true });
  await renderer.init();
} else {
  const renderer = new THREE.WebGLRenderer({ antialias: true });
}

务必在创建 WebGPURenderer 前检查 WebGPU.isAvailable()。 务必为不受支持的浏览器提供 WebGLRenderer 回退方案。

重要警告

切勿编写原始 GLSL 或 WGSL 字符串 — 务必使用 TSL 函数。WebGPU 会自动将 TSL 编译为 WGSL。WebGPU 后端不支持 GLSL。

切勿将 ShaderMaterial 与 WebGPURenderer 搭配使用 — 应改用结合 TSL 的 NodeMaterial。

切勿将 requestAnimationFrame 与 WebGPURenderer 搭配使用 — 务必使用 renderer.setAnimationLoop()。

切勿将 EffectComposer(three/examples)与 WebGPURenderer 搭配使用 — 应改用结合 TSL 节点的 PostProcessing 类。


节点材质

每种传统 Three.js 材质都有对应的基于节点的材质。传统材质与 WebGPURenderer 搭配使用时会自动转换,但节点材质可提供完整的 TSL 自定义能力。

材质映射
传统材质节点材质
MeshBasicMaterialMeshBasicNodeMaterial
MeshStandardMaterialMeshStandardNodeMaterial
MeshPhysicalMaterialMeshPhysicalNodeMaterial
MeshPhongMaterialMeshPhongNodeMaterial
MeshLambertMaterialMeshLambertNodeMaterial
LineBasicMaterialLineBasicNodeMaterial
LineDashedMaterialLineDashedNodeMaterial
PointsMaterialPointsNodeMaterial
SpriteMaterialSpriteNodeMaterial

务必从 'three/webgpu' 导入节点材质,而不是从 'three' 导入。

NodeMaterial 输入属性

所有属性都接受 TSL 节点值。所有属性均为可选项,并会覆盖默认值。

常见输入(所有节点材质):

属性TSL 类型用途
.colorNodevec4基础颜色
.opacityNodefloat不透明度
.normalNodevec3替换法线贴图
.emissiveNodecolor自发光输出
.positionNodevec3顶点位移
.fragmentNodevec4完全替换片元着色器
.vertexNodevec4完全替换顶点着色器
.outputNodevec4覆盖最终输出
.aoNodefloat环境光遮蔽
.alphaTestNodefloatAlpha 测试阈值
.depthNodefloat自定义深度
.castShadowNodevec4覆盖阴影投射

Standard/Physical 输入:

属性TSL 类型用途
.metalnessNodefloat金属度
.roughnessNodefloat粗糙度
.envNodecolor环境贴图
.lightsNode—覆盖光照模型

仅限 Physical 的输入: .clearcoatNode、.clearcoatRoughnessNode、.clearcoatNormalNode、.sheenNode、.iridescenceNode、.iridescenceIORNode、.iridescenceThicknessNode、.specularIntensityNode、.specularColorNode、.iorNode、.transmissionNode、.thicknessNode、.attenuationDistanceNode、.attenuationColorNode、.dispersionNode、.anisotropyNode。


TSL(Three 着色语言)

TSL 是一种基于 JavaScript 的节点图系统,可编译为 GLSL(WebGL2)和 WGSL(WebGPU)。它完全取代原始着色器字符串。

类型系统
类别函数
标量float()、int()、uint()、bool()
向量vec2()、vec3()、vec4()、ivec2()、ivec3()、ivec4()、uvec2()、uvec3()、uvec4()
矩阵mat2()、mat3()、mat4()
颜色color()
转换.toFloat()、.toVec3()、.toColor()
变量和 Uniform
函数用途
uniform(value)GPU 端动态值
toVar(node)可复用的着色器变量
toConst(node)内联常量
varying(node)顶点到片元的插值
vertexStage(node)强制在顶点着色器中计算
attribute(name, type)访问缓冲区属性

Uniform 支持回调:.onRenderUpdate(fn)、.onFrameUpdate(fn)、.onObjectUpdate(fn)。

运算符

所有运算符都可以在 TSL 节点上链式调用:

  • 算术: .add()、.sub()、.mul()、.div()、.mod()
  • 比较: .equal()、.notEqual()、.lessThan()、.greaterThan()、.lessThanEqual()、.greaterThanEqual()
  • 逻辑: .and()、.or()、.not()、.xor()
  • 赋值: .assign()、.addAssign()、.subAssign()、.mulAssign()、.divAssign()
  • 按位: .bitAnd()、.bitOr()、.bitXor()、.shiftLeft()、.shiftRight()
几何节点
类别节点
位置positionGeometry、positionLocal、positionWorld、positionView、positionWorldDirection、positionViewDirection
法线normalGeometry、normalLocal、normalView、normalWorld
切线tangentGeometry、tangentLocal、tangentView、tangentWorld
UVuv(index)
屏幕screenUV、screenCoordinate、screenSize
视口viewportUV、viewportCoordinate、viewportSize
相机和模型节点
  • 相机: cameraNear、cameraFar、cameraPosition、cameraProjectionMatrix、cameraViewMatrix、cameraWorldMatrix、cameraNormalMatrix
  • 模型: modelViewMatrix、modelNormalMatrix、modelWorldMatrix、modelPosition、modelScale、modelDirection
动画节点
节点用途
time自启动以来经过的秒数
deltaTime帧间隔秒数
oscSine(timer)正弦振荡器(0-1)
oscSquare(timer)方波振荡器
oscTriangle(timer)三角波振荡器
oscSawtooth(timer)锯齿波振荡器
纹理操作
函数用途
texture(tex, uv, level)通过插值进行采样
textureLoad(tex, uv, level)不进行插值地采样
textureStore(tex, uv, value)写入存储纹理
textureSize(tex, level)获取纹理尺寸
cubeTexture(tex, uvw, level)采样立方体贴图
triplanarTexture(texX, texY, texZ, scale, position, normal)三平面映射
控制流

始终使用大写的 If——小写的 if 属于 JavaScript,而不是 TSL。

If(condition, () => {
  // true branch
}).ElseIf(otherCondition, () => {
  // else-if branch
}).Else(() => {
  // false branch
});
  • select(condition, trueVal, falseVal) — 三元运算符
  • Loop(count, ({ i }) => { }) — GPU 循环,支持 Break()、Continue()
  • Switch(value).Case(val, fn).Default(fn) — 不会贯穿执行
  • Discard() — 丢弃片元
  • Return() — 提前返回
函数定义
const myFn = Fn(([param1, param2]) => {
  return param1.add(param2);
});
// Call: myFn(nodeA, nodeB)

计算着色器

WebGPU 通过 TSL 支持通用 GPU 计算。WebGL 回退模式下不支持计算着色器。

设置
import { compute, storage } from 'three/webgpu';

const computeNode = compute(shaderFn, count, workgroupSize);
await renderer.computeAsync(computeNode);

始终使用 await renderer.computeAsync()——计算调度是异步的。

存储和原子操作
  • 存储: storage(attribute, type, count)、storageTexture(texture)
  • 原子操作: atomicAdd()、atomicSub()、atomicMax()、atomicMin()、atomicAnd()、atomicOr()、atomicXor()、atomicStore()、atomicLoad()
  • 屏障: workgroupBarrier()、storageBarrier()、textureBarrier()
  • 内置 ID: workgroupId、localId、globalId、numWorkgroups、subgroupSize

WebGPU 后期处理

切勿将 WebGL 的 EffectComposer 与 WebGPURenderer 搭配使用。请改用 PostProcessing 类。

import { PostProcessing } from 'three/webgpu';
import { bloom, renderOutput } from 'three/tsl';

const postProcessing = new PostProcessing(renderer);
const scenePass = renderOutput(scene, camera);
postProcessing.outputNode = bloom(scenePass);
可用的后期处理节点

bloom()、dof()、fxaa()、smaa()、gaussianBlur()、ssr()、ssgi()、ao()、chromaticAberration()、film()、dotScreen()、sobel()、afterImage()、anamorphic()、denoise()、lut3D()、motionBlur()、outline()、rgbShift()、transition()、traa()、renderOutput()

颜色操作

luminance()、saturation()、vibrance()、hue()、posterize()、grayscale()、sepia()

混合模式

blendBurn()、blendDodge()、blendOverlay()、blendScreen()、blendColor()


从 WebGL 迁移到 WebGPU

步骤操作
1将 import * as THREE from 'three' 替换为 import * as THREE from 'three/webgpu'
2将 new WebGLRenderer() 替换为 new WebGPURenderer(),并添加 await renderer.init()
3将经典材质替换为对应的 NodeMaterial(也可以保留经典材质——它们会自动转换)
4将 EffectComposer 替换为 PostProcessing 类和 TSL 后期处理节点
5将原始 GLSL ShaderMaterial 替换为基于 TSL 的 NodeMaterial
6将 requestAnimationFrame 替换为 renderer.setAnimationLoop()

使用 WebGPURenderer 时,务必将入口点设为 async——renderer.init() 会返回一个 Promise。


参考链接

官方来源

评论

支持 Markdown