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. 01WebGPURenderer の初期化と利用可否の確認
  2. 02TSL によるノードマテリアルの構築
  3. 03コンピュートシェーダーによる GPU 計算
  4. 04WebGPU ポストプロセスの設定
  5. 05WebGL からの移行手順
  6. 06WebGL フォールバックの案内

活用シーン

  1. 01Three.js シーンの WebGPU 描画設定
  2. 02TSL によるマテリアルとシェーディングの記述
  3. 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 と一緒にインストールされる参考資料やスクリプト。

.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() を呼び出してください。 requestAnimationFrame の代わりに、必ず renderer.setAnimationLoop(callback) を使用してください。 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 にコンパイルします。GLSL は WebGPU バックエンドではサポートされません。

WebGPURenderer で ShaderMaterial を使用してはいけません。代わりに TSL と NodeMaterial を使用してください。

WebGPURenderer で requestAnimationFrame を使用してはいけません。必ず renderer.setAnimationLoop() を使用してください。

WebGPURenderer で EffectComposer(three/examples)を使用してはいけません。代わりに 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アンビエントオクルージョン
.alphaTestNodefloatアルファテストのしきい値
.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 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
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 は 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 への移行

手順操作
1import * as THREE from 'three' を import * as THREE from 'three/webgpu' に置き換えます
2new WebGLRenderer() を new WebGPURenderer() に置き換え、await renderer.init() を追加します
3従来のマテリアルを NodeMaterial 相当のものに置き換えます(または従来のものをそのまま使用します。自動変換されます)
4EffectComposer を PostProcessing クラスと TSL ポストプロセスノードに置き換えます
5生の GLSL ShaderMaterial を TSL ベースの NodeMaterial に置き換えます
6requestAnimationFrame を renderer.setAnimationLoop() に置き換えます

WebGPURenderer を使用する場合は、必ずエントリーポイントを async にしてください。renderer.init() は Promise を返します。


参考リンク

公式ソース

コメント