threejs-impl-webgpu について
threejs-impl-webgpu は、Three.js 開発者向けの WebGPU 実装解説スキルです。WebGPURenderer、TSL、ノードマテリアル、コンピュートシェーダー、ポストプロセスを扱い、API は実験段階と説明しています。
主な機能
- 01WebGPURenderer の初期化と利用可否の確認
- 02TSL によるノードマテリアルの構築
- 03コンピュートシェーダーによる GPU 計算
- 04WebGPU ポストプロセスの設定
- 05WebGL からの移行手順
- 06WebGL フォールバックの案内
活用シーン
- 01Three.js シーンの WebGPU 描画設定
- 02TSL によるマテリアルとシェーディングの記述
- 03WebGL 描画ワークフローの 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 と一緒にインストールされる参考資料やスクリプト。
.gitkeepreferences/anti-patterns.mdexamples.mdmethods.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() を呼び出してください。
requestAnimationFrame の代わりに、必ず renderer.setAnimationLoop(callback) を使用してください。
init() が完了する前に renderer.render() を呼び出してはいけません。実行時エラーが発生します。
ブラウザーのサポート状況
| ブラウザー | バージョン | 状況 |
|---|---|---|
| Chrome | 113+ | 完全サポート |
| Edge | 113+ | 完全サポート |
| Safari | 18+ | サポート |
| 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 にコンパイルします。GLSL は WebGPU バックエンドではサポートされません。
WebGPURenderer で ShaderMaterial を使用してはいけません。代わりに TSL と NodeMaterial を使用してください。
WebGPURenderer で requestAnimationFrame を使用してはいけません。必ず renderer.setAnimationLoop() を使用してください。
WebGPURenderer で EffectComposer(three/examples)を使用してはいけません。代わりに TSL ノードと PostProcessing クラスを使用してください。
ノードマテリアル
従来の Three.js マテリアルには、それぞれノードベースの同等品があります。従来のマテリアルは WebGPURenderer で使用すると自動変換されますが、ノードマテリアルを使うと TSL による完全なカスタマイズが可能です。
マテリアルの対応表
| 従来のマテリアル | ノードマテリアル |
|---|---|
MeshBasicMaterial | MeshBasicNodeMaterial |
MeshStandardMaterial | MeshStandardNodeMaterial |
MeshPhysicalMaterial | MeshPhysicalNodeMaterial |
MeshPhongMaterial | MeshPhongNodeMaterial |
MeshLambertMaterial | MeshLambertNodeMaterial |
LineBasicMaterial | LineBasicNodeMaterial |
LineDashedMaterial | LineDashedNodeMaterial |
PointsMaterial | PointsNodeMaterial |
SpriteMaterial | SpriteNodeMaterial |
ノードマテリアルは必ず 'three/webgpu' からインポートし、'three' からはインポートしないでください。
NodeMaterial の入力プロパティ
すべてのプロパティで TSL ノードの値を使用できます。いずれも省略可能で、省略した場合はデフォルト値が使われます。
共通の入力(すべてのノードマテリアル):
| プロパティ | TSL 型 | 用途 |
|---|---|---|
.colorNode | vec4 | ベースカラー |
.opacityNode | float | 不透明度 |
.normalNode | vec3 | 法線マップの置き換え |
.emissiveNode | color | 発光出力 |
.positionNode | vec3 | 頂点変位 |
.fragmentNode | vec4 | フラグメントシェーダー全体の置き換え |
.vertexNode | vec4 | 頂点シェーダー全体の置き換え |
.outputNode | vec4 | 最終出力の上書き |
.aoNode | float | アンビエントオクルージョン |
.alphaTestNode | float | アルファテストのしきい値 |
.depthNode | float | カスタム深度 |
.castShadowNode | vec4 | シャドウキャストの上書き |
Standard/Physical の入力:
| プロパティ | TSL 型 | 用途 |
|---|---|---|
.metalnessNode | float | 金属度 |
.roughnessNode | float | 粗さ |
.envNode | color | 環境マップ |
.lightsNode | — | ライティングモデルの上書き |
Physical のみの入力: .clearcoatNode、.clearcoatRoughnessNode、.clearcoatNormalNode、.sheenNode、.iridescenceNode、.iridescenceIORNode、.iridescenceThicknessNode、.specularIntensityNode、.specularColorNode、.iorNode、.transmissionNode、.thicknessNode、.attenuationDistanceNode、.attenuationColorNode、.dispersionNode、.anisotropyNode。
TSL(Three Shading Language)
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(value) | GPU 側の動的な値 |
toVar(node) | 再利用可能なシェーダー変数 |
toConst(node) | インライン定数 |
varying(node) | 頂点からフラグメントへの補間 |
vertexStage(node) | 頂点シェーダーでの計算を強制 |
attribute(name, type) | バッファ属性にアクセス |
ユニフォームはコールバックに対応しています:.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 |
| UV | uv(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 は TSL ではなく JavaScript です。
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 のポストプロセス
WebGPURenderer では、WebGL の EffectComposer を絶対に使用しないでください。代わりに 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 を返します。
参考リンク
- references/methods.md — WebGPURenderer、NodeMaterial、TSL、compute の API シグネチャ
- references/examples.md — WebGPU シーンの動作するコード例
- references/anti-patterns.md — よくある間違いとその回避方法