threejs-shaders について
カスタム GPU シェーダーの作成や組み込みマテリアルの拡張を行う Three.js 開発者向けスキルです。データの受け渡し、GLSL のデバッグ、性能確認を扱い、可能な場合は既存の PBR 動作を維持します。
主な機能
- 01ShaderMaterial と RawShaderMaterial の作成
- 02uniform と varying の明示的な受け渡し
- 03onBeforeCompile による組み込みマテリアルの拡張
- 04GLSL と座標空間の問題の診断
- 05シェーダー負荷の確認と所有リソースの解放
活用シーン
- 01ディスプレイスメント、フレネル、溶解、グラデーション効果の作成
- 02組み込み PBR を維持した効果の追加
- 03シェーダーのコンパイルや表示問題の調査
- 04リリース前の GPU 負荷確認
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ akillness/ jeo-skills --skill threejs-shadersインストール後、Claude Code で/threejs-shadersを入力して読み込まれたか確認します。
同梱ファイルevals/evals.jsonSKILL.toon
詳細
Three.js シェーダー
カスタム GPU プログラムや、安全な組み込みマテリアルの拡張にはこのスキルを使用してください。PBR サーフェスの選択は threejs-materials に、テクスチャ/UV データは threejs-textures に、フルスクリーンのコンポーザーエフェクトは threejs-postprocessing に振り分けてください。
このスキルを使用する場面
ShaderMaterialまたはRawShaderMaterialの頂点/フラグメントプログラムを記述する- uniform/varying を通じて、時間、色、テクスチャ、変換、インスタンスごとのデータを渡す
- ディスプレイスメント、フレネル、ディゾルブ、グラデーション、ノイズ、リムライト、カスタムエフェクトを実装する
- PBR の動作を置き換えずに、
onBeforeCompileで組み込みマテリアルを拡張する - GLSL のコンパイル、座標空間、精度、GPU コストに関する問題を診断する
手順
ステップ 1:影響が最も小さいシェーダーパスを選択する
| 必要なこと | 推奨パス |
|---|---|
| メッシュの完全なカスタムレンダリング | ShaderMaterial |
| 宣言/Three.js による挿入を完全に制御する | RawShaderMaterial |
| Standard/Physical の PBR を維持し、小規模なエフェクトを追加する | onBeforeCompile |
| フルスクリーンのスクリーンスペース処理 | threejs-postprocessing 経由の ShaderPass |
必要なライティング/PBR の動作が組み込みマテリアルにすでに備わっている場合は、組み込みマテリアルから始めてください。 ビジュアルモデルが本当に異なる場合に限り、カスタムマテリアルを使用してください。
ステップ 2:データフローを明確にする
const material = new THREE.ShaderMaterial({
uniforms: {
uTime: { value: 0 },
uColor: { value: new THREE.Color("#4f8cff") },
},
vertexShader: `
varying vec2 vUv;
void main() {
vUv = uv;
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
`,
fragmentShader: `
uniform vec3 uColor;
varying vec2 vUv;
void main() {
gl_FragColor = vec4(uColor * vec3(vUv.y), 1.0);
}
`,
});
uniform はドローコール中に一定であり、varying は頂点シェーダーで書き込まれ、フラグメントシェーダーに補間されます。変数名やコメントで座標空間(local、world、view、clip、uv)を明示してください。シェーダーの不具合の多くは、座標空間の不一致が暗黙になっていることが原因です。
ステップ 3:意図した uniform の値だけを更新する
material.uniforms.uTime.value = elapsedSeconds;
uniform オブジェクトを毎フレーム置き換えず、.value を変更してください。可能であれば、Color、Vector、テクスチャの各オブジェクトを再利用してください。インスタンスごとに変化を付けるには、インスタンスごとにマテリアルを作成するのではなく、サポートされている属性を使用してください。
ステップ 4:組み込みマテリアルを慎重に拡張する
onBeforeCompile は内部シェーダーチャンクに依存しており、Three.js のリビジョンによって変更される場合があります。置換範囲を狭く保ち、プログラムのバリエーションがアプリケーションの状態に依存する場合は material.customProgramCacheKey() を設定し、固定されたプロジェクトバージョンでテストしてください。バージョン管理されたテスト環境なしに、ソース文字列の置換を恒久的な抽象化として使用しないでください。
ステップ 5:コンパイル、見た目、パフォーマンスの動作を検証する
- ブラウザーのシェーダーコンパイルログを確認し、詳細をデバッグする前に最小限のシェーダーに絞り込んでください。
- 診断用のカラー出力を使って、既知の座標/法線/UV のケースを少なくとも 1 つ検証してください。
- 製品でサポートされている場合は、対象のモバイルハードウェアで精度と微分関数をテストしてください。
- リリース前に、フラグメントのオーバードロー、テクスチャサンプル、ループ、マテリアルのバリエーションを測定してください。
- 機能が所有するカスタムマテリアルとレンダーターゲットは、終了時に破棄してください。
例
フレネルリム信号
同じ空間で正規化した法線とビュー方向を計算し、その内積からリム項を導出してください。正面向きの角度と浅い角度をテストしてください。空間変換が負しい、または不正確だと、フレネルエフェクトが反転したり、カメラに固定されたように見えたりすることがよくあります。
頂点ディスプレイスメント
オブジェクト/ローカル空間で変位させ、変形後の位置/法線の処理を一貫したライティングモデルに渡してください。高周波のディスプレイスメントには十分なジオメトリ密度が必要です。メッシュに含まれていないシルエットのディテールをシェーダーで作り出すことはできません。
ベストプラクティス
- 単色を描画する最小限のシェーダーから始め、その後データフローを追加してください。
- 座標空間を明示し、数学的に必要な場合にのみ正規化してください。
- レンダーループ内で uniform を更新する際に、メモリー割り当てが発生しないようにしてください。
- PBR ライティングを再実装するより、組み込みマテリアルの拡張を優先してください。
- 対象 GPU でプロファイルしてください。視覚的には小さなフラグメントエフェクトでも、フレーム時間の大部分を占めることがあります。