mcpField
T
threejs-syntax-shaders

threejs-syntax-shaders

github.com/impertio-studio開発23143 回インストール30 週間前に更新
リポジトリ

threejs-syntax-shaders について

threejs-syntax-shaders は、Three.js 開発者向けのシェーダーリファレンススキルです。マテリアル、GLSL 構文、カスタムシェーダーの作成やデバッグで起きやすい問題を扱います。

主な機能

  1. 01ShaderMaterial と RawShaderMaterial の比較
  2. 02uniform の型と値の形式の解説
  3. 03ShaderChunk と onBeforeCompile の説明
  4. 04GLSL3 構文と define 更新の解説
  5. 05シェーダーのコンパイルエラーの注意点

活用シーン

  1. 01Three.js のカスタムマテリアルシェーダーの作成
  2. 02外部 GLSL シェーダーの Three.js への移植
  3. 03uniform や GLSL のコンパイル問題の調査

インストール

コマンドをコピーしてターミナルで実行します。

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

インストール後、Claude Code で/threejs-syntax-shadersを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

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

詳細

threejs-syntax-shaders

クイックリファレンス

ShaderMaterial と RawShaderMaterial の比較
項目ShaderMaterialRawShaderMaterial
組み込みユニフォーム自動的に挿入されますなし -- すべて自分で宣言する必要があります
組み込み属性自動的に宣言されますなし -- すべて自分で宣言する必要があります
#include <chunk>対応しています対応していません
精度宣言自動ですprecision mediump float; を追加する必要があります
用途Three.js のレンダリングを拡張するシェーダーを完全に制御する、外部シェーダーを移植する
パフォーマンス未使用の組み込み要素によるわずかなオーバーヘッドシェーダーのオーバーヘッドは最小限
ユニフォーム型の対応表
GLSL 型JavaScript の値
float{ value: 1.0 }
int{ value: 1 }
bool{ value: true }
vec2{ value: new THREE.Vector2() }
vec3{ value: new THREE.Vector3() } または { value: new THREE.Color() }
vec4{ value: new THREE.Vector4() }
mat3{ value: new THREE.Matrix3() }
mat4{ value: new THREE.Matrix4() }
sampler2D{ value: texture }(THREE.Texture インスタンス)
samplerCube{ value: cubeTexture }
float[]{ value: [1.0, 2.0, 3.0] }
vec3[]{ value: [new THREE.Vector3(), ...] }
重要な警告

ユニフォームに値をそのまま絶対に渡さないでください。必ず { value: ... } でラップしてください。uniforms: { uTime: 0.0 } と記述してもエラーなく失敗します。必ず uniforms: { uTime: { value: 0.0 } } と記述してください。

ShaderMaterial のシェーダーでは、組み込みユニフォームや属性を絶対に宣言しないでください。Three.js が自動的に挿入します。再宣言すると GLSL のコンパイルエラーが発生します。

RawShaderMaterial のシェーダーでは、すべてのユニフォーム、属性、精度を必ず宣言してください。何も自動挿入されません。

glslVersion が THREE.GLSL3 の場合、gl_FragColor や texture2D() は絶対に使用しないでください。代わりに、宣言した out vec4 変数と texture() を使用してください。

defines を変更した後は、必ず material.needsUpdate = true を設定してください。defines はシェーダーにコンパイルされるため、変更するには再コンパイルが必要です。


ShaderMaterial

コンストラクター
import * as THREE from 'three';

const material = new THREE.ShaderMaterial({
  uniforms: {
    uTime: { value: 0.0 },
    uColor: { value: new THREE.Color(0x00ff00) },
    uTexture: { value: someTexture },
  },
  vertexShader: `
    varying vec2 vUv;
    void main() {
      vUv = uv;
      gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
    }
  `,
  fragmentShader: `
    uniform float uTime;
    uniform vec3 uColor;
    varying vec2 vUv;
    void main() {
      gl_FragColor = vec4(uColor * vUv.x, 1.0);
    }
  `,
  transparent: false,
  wireframe: false,
  side: THREE.FrontSide,
});
プロパティ
プロパティ型デフォルト説明
uniformsObject{}{ name: { value: ... } } 形式
uniformsGroupsArray[]ユニフォームバッファオブジェクト(UBO)
vertexShaderstring--GLSL 頂点シェーダーのソース
fragmentShaderstring--GLSL フラグメントシェーダーのソース
definesObject{}プリプロセッサの #define ディレクティブ
extensionsObject{}有効にする GLSL 拡張機能
wireframebooleanfalseワイヤーフレームレンダリング
lightsbooleanfalseライトのユニフォームをシェーダーに渡す
fogbooleanfalseフォグのユニフォームをシェーダーに渡す
clippingbooleanfalseクリッピング平面を有効にする
glslVersionstring | nullnullGLSL1 の場合は null、GLSL 3.0 ES の場合は THREE.GLSL3
defaultAttributeValuesObject--属性がない場合のフォールバック値

組み込みユニフォーム(ShaderMaterial のみ)

これらは自動的に挿入されます。自分で宣言してはいけません。

// Transform matrices
uniform mat4 modelMatrix;           // Object -> World
uniform mat4 modelViewMatrix;       // Object -> Camera
uniform mat4 projectionMatrix;      // Camera -> Clip
uniform mat4 viewMatrix;            // World -> Camera
uniform mat3 normalMatrix;          // Transpose inverse of modelViewMatrix

// Camera
uniform vec3 cameraPosition;        // Camera world position

// When lights: true
uniform vec3 ambientLightColor;
// Plus structured arrays for directional, point, spot, hemisphere lights

組み込み属性(ShaderMaterial のみ)

これらは自動的に挿入されます。自分で宣言してはいけません。

attribute vec3 position;    // Vertex position
attribute vec3 normal;      // Vertex normal
attribute vec2 uv;          // Primary UV coordinates
attribute vec2 uv2;         // Secondary UV (for aoMap, lightMap)
attribute vec4 tangent;     // Tangent vector (if computeTangents was called)
attribute vec3 color;       // Vertex color (if geometry has color attribute)

RawShaderMaterial

シェーダーソースを完全に制御する必要がある場合に使用します。何も自動挿入されません。

const material = new THREE.RawShaderMaterial({
  uniforms: {
    uModelViewMatrix: { value: new THREE.Matrix4() },
    uProjectionMatrix: { value: new THREE.Matrix4() },
  },
  vertexShader: `
    precision highp float;
    attribute vec3 position;
    uniform mat4 uModelViewMatrix;
    uniform mat4 uProjectionMatrix;
    void main() {
      gl_Position = uProjectionMatrix * uModelViewMatrix * vec4(position, 1.0);
    }
  `,
  fragmentShader: `
    precision highp float;
    void main() {
      gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
    }
  `,
});

RawShaderMaterial では、両方のシェーダーの先頭に precision highp float;(または mediump)を必ず追加してください。精度宣言を省略すると、モバイル端末や一部のデスクトップ用ドライバーで GLSL のコンパイルエラーが発生します。


ShaderChunk -- Three.js のシェーダーコードの再利用

THREE.ShaderChunk には、すべての内部シェーダーフラグメントが含まれています。ShaderMaterial では #include <chunk_name> を使用してください(RawShaderMaterial では使用できません)。

共通チャンク
チャンク目的
<common>共通定数と関数(PI、saturate など)
<fog_pars_vertex> / <fog_vertex>フォグ対応(頂点)
<fog_pars_fragment> / <fog_fragment>フォグ対応(フラグメント)
<shadowmap_pars_vertex> / <shadowmap_vertex>シャドウ対応(頂点)
<shadowmap_pars_fragment> / <shadowmap_fragment>シャドウ対応(フラグメント)
<lights_pars_begin>ライト構造体の宣言
<begin_vertex>position から transformed 変数を初期化
<project_vertex>modelViewMatrix と projectionMatrix を適用
<normal_fragment_begin>法線マッピングのセットアップ
<color_pars_vertex> / <color_vertex>頂点カラー対応
プログラムからチャンクにアクセスする
// Read the source of any chunk
console.log(THREE.ShaderChunk.common);
console.log(THREE.ShaderChunk.fog_pars_vertex);

onBeforeCompile -- 組み込みマテリアルへのパッチ適用

既存のマテリアルのシェーダーをコンパイル時に変更します。これにより、PBR ライティング、シャドウ、およびすべての組み込み機能が維持されます。

const material = new THREE.MeshStandardMaterial({ color: 0xff0000 });

material.onBeforeCompile = (shader) => {
  shader.uniforms.uTime = { value: 0.0 };

  shader.vertexShader = shader.vertexShader.replace(
    '#include <begin_vertex>',
    `
    #include <begin_vertex>
    transformed.y += sin(transformed.x * 5.0 + uTime) * 0.5;
    `
  );

  // Store reference for uniform updates
  material.userData.shader = shader;
};

// ALWAYS override customProgramCacheKey when using onBeforeCompile
material.customProgramCacheKey = () => 'my-wavy-material';

// In animation loop
if (material.userData.shader) {
  material.userData.shader.uniforms.uTime.value = clock.getElapsedTime();
}

onBeforeCompile を使用する場合は、必ず customProgramCacheKey() をオーバーライドしてください。そうしないと、Three.js がパッチ未適用のシェーダープログラムをキャッシュから再利用し、変更が気づかないうちに反映されなくなる場合があります。

uniform にアクセスする前に、material.userData.shader が存在することを必ず確認してください。シェーダーオブジェクトは初回レンダリング時に遅延生成され、material.needsUpdate = true にすると再作成される場合があります。


Defines -- プリプロセッサディレクティブ

const material = new THREE.ShaderMaterial({
  defines: {
    USE_FOG: '',           // #define USE_FOG
    MAX_LIGHTS: 4,         // #define MAX_LIGHTS 4
    EPSILON: '0.001',      // #define EPSILON 0.001
  },
  // ...shaders
});

実行時に defines を変更する方法:

material.defines.MAX_LIGHTS = 8;
material.needsUpdate = true;  // REQUIRED -- triggers recompilation

GLSL3 モード

const material = new THREE.ShaderMaterial({
  glslVersion: THREE.GLSL3,
  vertexShader: `
    in vec3 position;           // 'attribute' becomes 'in'
    uniform mat4 modelViewMatrix;
    uniform mat4 projectionMatrix;
    out vec3 vPosition;         // 'varying' becomes 'out'

    void main() {
      vPosition = position;
      gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
    }
  `,
  fragmentShader: `
    precision highp float;
    in vec3 vPosition;          // 'varying' becomes 'in'
    out vec4 fragColor;         // replaces gl_FragColor

    void main() {
      fragColor = vec4(vPosition * 0.5 + 0.5, 1.0);
    }
  `,
});
GLSL1 と GLSL3 の構文
GLSL1GLSL3コンテキスト
attributein頂点シェーダーの入力
varying(頂点)out頂点シェーダーの出力
varying(フラグメント)inフラグメントシェーダーの入力
gl_FragColorout vec4 を宣言フラグメントシェーダーの出力
texture2D()texture()テクスチャサンプリング
textureCube()texture()キューブテクスチャのサンプリング

uniform の更新パターン

// At creation
const material = new THREE.ShaderMaterial({
  uniforms: {
    uTime: { value: 0.0 },
    uResolution: { value: new THREE.Vector2(window.innerWidth, window.innerHeight) },
    uMouse: { value: new THREE.Vector2() },
  },
  vertexShader: '...',
  fragmentShader: '...',
});

// In animation loop -- update the .value property directly
function animate() {
  material.uniforms.uTime.value = performance.now() / 1000;
  material.uniforms.uMouse.value.set(mouseX, mouseY);
  renderer.render(scene, camera);
  requestAnimationFrame(animate);
}

uniform オブジェクト自体(例:material.uniforms.uTime = { value: 5 })を決して置き換えないでください。既存の .value プロパティを必ず変更してください。オブジェクトを置き換えると、内部参照が壊れます。


参考リンク

公式ソース

コメント