threejs-materials について
three.js r186 でマテリアルを扱う開発者向けのリファレンススキルです。マテリアルの選択、テクスチャ設定、WebGL と WebGPU の描画方法を説明します。
主な機能
- 01組み込みマテリアルの概要
- 02PBR と層状マテリアルの設定
- 03テクスチャの色空間と UV の解説
- 04WebGLRenderer 向け GLSL シェーダー
- 05WebGPU と TSL のマテリアル解説
活用シーン
- 01three.js シーンのマテリアル選択
- 02PBR テクスチャと UV チャンネルの設定
- 03ガラスなど層状表面の作成
- 04カスタム WebGL シェーダーの作成
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ cloudai-x/ threejs-skills --skill threejs-materialsインストール後、Claude Code で/threejs-materialsを入力して読み込まれたか確認します。
詳細
Three.js マテリアル
three.js r186 を対象としています。例では WebGLRenderer を使用し、WebGPU と TSL のセクションでは WebGPURenderer を使用します。
クイックスタート
import * as THREE from "three";
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 100);
camera.position.set(0, 0, 3);
// PBR material - the default choice for lit, realistic surfaces
const material = new THREE.MeshStandardMaterial({
color: 0x00aaff,
roughness: 0.35,
metalness: 0.1,
});
const mesh = new THREE.Mesh(new THREE.SphereGeometry(1, 48, 32), material);
scene.add(mesh);
scene.add(new THREE.HemisphereLight(0xffffff, 0x444444, 1)); // lit materials render black without lights
const light = new THREE.DirectionalLight(0xffffff, 2);
light.position.set(3, 3, 3);
scene.add(light);
function animate() {
mesh.rotation.y += 0.01;
renderer.render(scene, camera);
}
renderer.setAnimationLoop(animate);
マテリアルの種類の概要
| マテリアル | 用途 | ライティング |
|---|---|---|
| MeshBasicMaterial | ライティングなしの色、テクスチャ、ワイヤーフレーム | なし |
| MeshLambertMaterial | マットな拡散反射面 | 拡散反射 |
| MeshPhongMaterial | 光沢のあるプラスチック、簡易的な鏡面反射 | 拡散反射+鏡面反射 |
| MeshStandardMaterial | PBR のメタルネス/ラフネスワークフロー | PBR |
| MeshPhysicalMaterial | クリアコート、透過、シーン、虹色効果を加えた PBR | PBR |
| MeshToonMaterial | セルシェーディング | トゥーン階調 |
| MeshMatcapMaterial | matcap テクスチャに焼き込まれたライティング表現。ライトは不要 | 焼き込み済み |
| ShadowMaterial | 受け取った影のみを表示する透明な面 | 影のみ |
| PointsMaterial | 点群 | なし |
| LineBasicMaterial / LineDashedMaterial | 線 | なし |
| ShaderMaterial / RawShaderMaterial | カスタム GLSL。WebGLRenderer のみ | カスタム |
カラーのテクスチャデータ(map、emissiveMap、specularMap、sheenColorMap、specularColorMap、LDR matcap、カラーとして使う canvas や video)には texture.colorSpace = THREE.SRGBColorSpace が必要です。設定しないと、色が薄く表示されます。スカラーのマップ(normal、bump、displacement、roughness、metalness、ao、alpha、トゥーンの gradientMap)はデフォルトのままにします。HDR ローダーは独自の色空間を設定します。
MeshBasicMaterial
ライティング計算を行いません。高速で、常に表示されます。reflectivity(0〜1)と combine(THREE.MultiplyOperation、THREE.MixOperation、THREE.AddOperation)を使う envMap に対応しています。specularMap(sRGB)は env-map の寄与をマスクします。
const map = await new THREE.TextureLoader().loadAsync("color.jpg");
map.colorSpace = THREE.SRGBColorSpace;
const material = new THREE.MeshBasicMaterial({
color: 0xffffff, // multiplied with the map
map,
transparent: true,
opacity: 0.5,
side: THREE.DoubleSide, // FrontSide (default), BackSide, DoubleSide
fog: true, // affected by scene fog
});
MeshLambertMaterial と MeshPhongMaterial
Lambert は拡散反射のみです。Phong は鏡面ハイライトを追加します。Standard が重すぎる場合に使える、簡易的な代替手段です。
const lambert = new THREE.MeshLambertMaterial({
color: 0x00ff00,
emissive: 0x111111, // self-illumination color
emissiveIntensity: 1,
});
const phong = new THREE.MeshPhongMaterial({
color: 0x0000ff,
specular: 0x111111, // highlight color
shininess: 30, // higher = sharper highlight
flatShading: false, // flat vs smooth normals
});
どちらも map、emissiveMap、specularMap(sRGB。env-map の反射と、Phong のハイライトをマスクします)、normalMap、bumpMap、displacementMap、aoMap、envMap、envMapIntensity、envMapRotation に対応しています。
MeshStandardMaterial(PBR)
物理ベースレンダリングです。リアルな結果を得るのにおすすめです。
const map = await new THREE.TextureLoader().loadAsync("color.jpg");
map.colorSpace = THREE.SRGBColorSpace;
const ormMap = await new THREE.TextureLoader().loadAsync("orm.jpg"); // glTF ORM: ao red, roughness green, metalness blue; scalar: keep default
const material = new THREE.MeshStandardMaterial({
color: 0xffffff, // multiplied with the map
roughness: 1.0, // 0 = mirror, 1 = fully diffuse; multiplied by roughnessMap (green)
metalness: 1.0, // 0 = dielectric, 1 = metal; multiplied by metalnessMap (blue), so keep 1 with a map
map,
roughnessMap: ormMap,
metalnessMap: ormMap,
normalMap: null, // surface detail; scale with normalScale (a Vector2)
aoMap: ormMap, // ambient occlusion (red); intensity with aoMapIntensity
displacementMap: null, // vertex displacement; scale with displacementScale, offset with displacementBias
emissive: 0x000000,
emissiveIntensity: 1,
emissiveMap: null, // sRGB
envMap: null, // or rely on scene.environment (see below)
fog: true,
});
lightMap(lightMapIntensity と併用)は、aoMap が遮蔽を焼き込むのと同様に、間接光を焼き込みます。HDR または EXR の lightMap は LinearSRGBColorSpace で、ローダーによって設定されます。
UV チャンネル:aoMap と lightMap が参照するチャンネルを選択
UV マッピングされた各テクスチャは、texture.channel で選択した属性をサンプリングします。0 は uv(デフォルト)、1 は uv1、2 は uv2、3 は uv3 を参照します。aoMap と lightMap に 2 つ目の UV セットは不要です。channel を変更しない限り、uv をサンプリングします。GLTFLoader は TEXCOORD_1 を uv1 として読み込み、channel も設定します。
const aoMap = await new THREE.TextureLoader().loadAsync("ao.jpg"); // scalar: keep default
const material = new THREE.MeshStandardMaterial({ aoMap }); // samples uv: no extra attribute needed
// Alternative for a separate unwrap (a baked AO or light map): copy your baker's u,v pairs into uv1
const bakedUv = new THREE.Float32BufferAttribute(mesh.geometry.attributes.position.count * 2, 2); // zero-filled until you copy them in
mesh.geometry.setAttribute("uv1", bakedUv); mesh.material = material;
aoMap.channel = 1; // this material now samples uv1 instead of uv
MeshPhysicalMaterial(高度な PBR)
MeshStandardMaterial を拡張し、レイヤーとボリュームの機能を備えています。ほとんどの機能にはテクスチャ版があります:clearcoatMap、clearcoatRoughnessMap、clearcoatNormalMap、transmissionMap、thicknessMap、iridescenceMap、iridescenceThicknessMap、sheenColorMap、sheenRoughnessMap、anisotropyMap、specularIntensityMap、specularColorMap。
const material = new THREE.MeshPhysicalMaterial({
// Clearcoat (car paint, lacquer)
clearcoat: 1.0, // 0 = none, 1 = full coat
clearcoatRoughness: 0.1,
// Transmission (glass, water) - refracts the opaque objects and scene.background behind it
transmission: 1.0, // 0 = opaque, 1 = fully transmissive
thickness: 0.5, // volume thickness for refraction
attenuationDistance: 1, // world units; Infinity (the default) = no absorption
attenuationColor: new THREE.Color(0xffaa66), // white light turns this color after attenuationDistance
ior: 1.5, // index of refraction, 1 to 2.333
// Sheen (fabric, velvet)
sheen: 1.0,
sheenColor: new THREE.Color(0xffffff),
sheenRoughness: 0.5,
// Iridescence (soap bubbles, oil slicks)
iridescence: 1.0,
iridescenceIOR: 1.3,
iridescenceThicknessRange: [100, 400], // nanometers
// Anisotropy (brushed metal); direction with anisotropyRotation
anisotropy: 1.0,
// Dispersion (prismatic glass); retroreflectivity (road signs, safety gear)
dispersion: 0.0,
retroreflectivity: 0.0,
// Specular overrides: specularIntensity, specularColor (plus their maps)
});
ガラス:表面を滑らかにし、その背後に屈折させるものを配置した透過表現です。
const glass = new THREE.MeshPhysicalMaterial({
color: 0xffffff,
metalness: 0,
roughness: 0,
transmission: 1,
thickness: 0.5,
ior: 1.5,
});
// transmission refracts the opaque objects and background behind it; scene.environment adds its reflections
MeshToonMaterial
セルシェーディングです。gradient map はカラーではないデータなので、デフォルトの色空間のままにします。
const steps = new Uint8Array([120, 200]); // two shading steps
const gradientMap = new THREE.DataTexture(steps, 2, 1, THREE.RedFormat);
gradientMap.minFilter = THREE.NearestFilter; // hard steps; LinearFilter blends them
gradientMap.magFilter = THREE.NearestFilter;
gradientMap.needsUpdate = true;
const material = new THREE.MeshToonMaterial({ color: 0x00ff00, gradientMap });
MeshNormalMaterial と MeshDepthMaterial
// Normals encoded as RGB - debugging and flat illustrative looks
const normals = new THREE.MeshNormalMaterial({ flatShading: false, wireframe: false });
// Depth as grayscale (BasicDepthPacking, the default); RGBADepthPacking packs it for reading back in a shader
const depth = new THREE.MeshDepthMaterial();
PointsMaterial
点群用です。size はピクセル単位です。sizeAttenuation(デフォルト。透視カメラのみ)を有効にすると、キャンバスの高さの半分を乗じ、点のビュー空間での深度で除算します。
const geometry = new THREE.BufferGeometry();
geometry.setAttribute("position", new THREE.Float32BufferAttribute([0, 0, 0, 1, 0.5, 0, 0.5, 1, 0], 3));
const material = new THREE.PointsMaterial({
color: 0xffffff,
size: 0.1,
sizeAttenuation: true, // scale with distance
alphaTest: 0.5, // with a map or alphaMap: discard fragments below this alpha
});
const points = new THREE.Points(geometry, material);
scene.add(points);
LineBasicMaterial と LineDashedMaterial
WebGL と WebGPU では、線プリミティブは常に幅 1 px で描画されます。linewidth、linecap、linejoin が影響するのは SVGRenderer のみです。WebGLRenderer で太い線を描画するには、three/addons/lines/ の LineGeometry と LineMaterial を使って Line2 を使用してください(linewidth の単位はピクセルです)。LineMaterial は ShaderMaterial なので、WebGPURenderer では three/addons/lines/webgpu/Line2.js の Line2 を使う必要があります。これは Line2NodeMaterial を使用します。
const geometry = new THREE.BufferGeometry();
geometry.setAttribute("position", new THREE.Float32BufferAttribute([-1, 0, 0, 1, 0, 0], 3));
const solid = new THREE.LineBasicMaterial({ color: 0xffffff }); // always 1 px
const dashed = new THREE.LineDashedMaterial({ color: 0xffffff, dashSize: 0.5, gapSize: 0.25 });
const line = new THREE.Line(geometry, dashed);
line.computeLineDistances(); // required, or the line draws solid
scene.add(line);
ShaderMaterial(WebGLRenderer のみ)
カスタム GLSL を使用し、three.js の uniform が自動的に挿入されます。常に GLSL ES 3.00 としてコンパイルされるため、texture()、textureLod()、dFdx が使えます。また、texture2D/gl_FragColor は引き続きエイリアスとして使用できます。glslVersion は設定しないでください。ShaderMaterial、RawShaderMaterial、onBeforeCompile には WebGPURenderer 用のパスがありません。WebGPURenderer では、ノードマテリアルと TSL を使用してください。
const timer = new THREE.Timer();
timer.connect(document); // pause when the tab is hidden
const material = new THREE.ShaderMaterial({
uniforms: { time: { value: 0 } },
vertexShader: `
varying vec2 vUv;
uniform float time;
void main() {
vUv = uv;
vec3 pos = position;
pos.z += sin(pos.x * 10.0 + time) * 0.1;
gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0);
}
`,
fragmentShader: `
varying vec2 vUv;
uniform float time;
void main() {
vec3 col = 0.5 + 0.5 * cos(time + vUv.xyx * 3.0);
gl_FragColor = vec4(col, 1.0);
}
`,
});
function animate() {
timer.update(); // first thing every frame, no argument
material.uniforms.time.value = timer.getElapsed();
renderer.render(scene, camera);
}
シェーダー内で自動的に宣言されるのは、modelMatrix、modelViewMatrix、projectionMatrix、viewMatrix、normalMatrix、cameraPosition と、属性の position、normal、uv です(InstancedMesh では instanceMatrix も宣言されますが、projectionMatrix * modelViewMatrix * instanceMatrix * vec4(pos, 1.0) のように自分で適用する必要があります。また、vertexColors を使う場合は color も宣言されます)。追加の uv セットと tangent は宣言されないため、in vec2 uv1; を自分で追加してください。
RawShaderMaterial(WebGLRenderer のみ)
宣言は前置されません(glslVersion による #version、SHADER_TYPE と SHADER_NAME の define、および自分で指定した defines のみが追加されます)。ただし、レンダラーは引き続き projectionMatrix、modelViewMatrix、viewMatrix、normalMatrix、modelMatrix、cameraPosition を設定するため、シェーダー内で宣言し、uniforms には決して渡さないでください。同じ名前のエントリーは描画ごとに上書きされる(modelMatrix、modelViewMatrix、normalMatrix)か、カメラの値を置き換えます(projectionMatrix、viewMatrix、cameraPosition)。
const material = new THREE.RawShaderMaterial({
glslVersion: THREE.GLSL3, // without it the shader is GLSL ES 1.00, which has no texture()
vertexShader: `
precision highp float;
in vec3 position;
uniform mat4 projectionMatrix;
uniform mat4 modelViewMatrix;
void main() {
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
`,
fragmentShader: `
precision highp float;
out highp vec4 fragColor; // your own output variable
void main() {
fragColor = vec4(1.0, 0.0, 0.0, 1.0);
}
`,
});
共通プロパティ
const material = new THREE.MeshBasicMaterial({ color: 0xff0000 });
material.visible = true;
material.transparent = false; // true for opacity below 1; toggling it after the first render needs needsUpdate
material.opacity = 1.0;
material.alphaTest = 0; // discard fragments with alpha below the value
material.side = THREE.FrontSide; // FrontSide, BackSide, DoubleSide
material.depthTest = true;
material.depthWrite = true;
material.blending = THREE.NormalBlending; // or AdditiveBlending, CustomBlending
material.polygonOffset = false; // with the two values below, fixes z-fighting
material.polygonOffsetFactor = 0;
material.polygonOffsetUnits = 0;
material.toneMapped = true; // false keeps exact colors (UI overlays)
material.dithering = false; // true reduces banding in gradients
material.vertexColors = false;
// Multiply and subtractive blending require premultiplied alpha (both renderers)
const material = new THREE.MeshBasicMaterial({ color: 0x8844ff });
material.blending = THREE.SubtractiveBlending; // same for THREE.MultiplyBlending
material.premultipliedAlpha = true; // without it the renderer logs an error and sets no blend function
// Stencil is off by default in both renderers: create the renderer with { stencil: true }
const maskMaterial = new THREE.MeshBasicMaterial({ colorWrite: false, depthWrite: false });
maskMaterial.stencilWrite = true; // master switch for the stencil test and write
maskMaterial.stencilRef = 1;
maskMaterial.stencilZPass = THREE.ReplaceStencilOp; // writes 1 where the mask draws; also stencilFail, stencilZFail
const contentMaterial = new THREE.MeshBasicMaterial({ color: 0xff0000, stencilWrite: true, stencilRef: 1 });
contentMaterial.stencilFunc = THREE.EqualStencilFunc; // draws only where the mask wrote 1
contentMaterial.stencilFuncMask = 0xff; // compare mask; stencilWriteMask masks the write (both default 0xff)
// draw the mask first: give its mesh a lower renderOrder than the content mesh
Mesh での複数マテリアルの使用
// One material per geometry group; BoxGeometry has six, in the order +x, -x, +y, -y, +z, -z
const geometry = new THREE.BoxGeometry(1, 1, 1);
const colors = [0xff0000, 0x00ff00, 0x0000ff, 0xffff00, 0xff00ff, 0x00ffff];
const mesh = new THREE.Mesh(geometry, colors.map((color) => new THREE.MeshBasicMaterial({ color })));
// Custom groups: start, count, material index. Indexed geometry counts indices (BoxGeometry has 36),
// non-indexed geometry counts vertices; ranges outside every group are not drawn
geometry.clearGroups();
geometry.addGroup(0, 18, 0);
geometry.addGroup(18, 18, 1);
環境マップ
正距円筒図法の HDR ファイルを使うと、シーン内のすべての PBR マテリアルに光を当て、反射させることができます。どちらのレンダラーも自動的にプリフィルタリングするため、PMREM の手順は不要です。
import { HDRLoader } from "three/addons/loaders/HDRLoader.js";
const env = await new HDRLoader().loadAsync("environment.hdr");
env.mapping = THREE.EquirectangularReflectionMapping; // without it a background draws as a flat quad
scene.environment = env; // lights and reflects PBR materials
scene.background = env;
scene.environmentIntensity = 0.8; // scene-wide dimmer; scene.environmentRotation tilts it
const cubeEnv = new THREE.CubeTextureLoader().load([
"px.jpg", "nx.jpg", "py.jpg", "ny.jpg", "pz.jpg", "nz.jpg",
]);
const material = new THREE.MeshStandardMaterial({ envMap: cubeEnv });
material.envMapIntensity = 1.5; // scales only this material's own envMap
material.envMapRotation = new THREE.Euler(0, Math.PI / 4, 0);
scene.environment は、どちらのレンダラーでも MeshStandardMaterial と MeshPhysicalMaterial に光を当てます。WebGLRenderer では MeshLambertMaterial と MeshPhongMaterial にも光を当てますが、WebGPURenderer は対応していません。
実行時の変更、複製、破棄
mesh.material.color.set(0xff0000); // uniform values: no recompile needed
mesh.material.roughness = 0.8;
// material.needsUpdate = true after changing a setting compiled into the shader:
// transparent, side, blending, flatShading, vertexColors, dithering, premultipliedAlpha, alphaHash,
// adding or removing a map slot, or shader source (alphaTest and envMap recompile by themselves)
const clone = mesh.material.clone(); // copies values; map slots share their textures, ShaderMaterial uniforms are cloned
ほかで使われていないマテリアルは破棄してください。material.dispose() を呼び出すと、その GPU プログラムが解放されます。これらのプログラムは、ほかのマテリアルから使われなくなると削除されます。テクスチャには個別に texture.dispose() が必要です。
パフォーマンスへの影響が大きい順:
- 複数のメッシュで同じマテリアルインスタンスを共有します。連続する描画でマテリアルが切り替わるたびに、レンダラーはマテリアルの uniform を再アップロードします(設定が同じ場合は、すでにコンパイル済みのプログラムが共有されます)。
- できるだけ不透明な描画を使用します。透明なマテリアルはオブジェクト単位で奥から手前へソートされ、不透明なオブジェクトの後に描画されます。
depthWrite: falseにしない限り深度も書き込まれるため、重なったレイヤーではオーバードローが発生し、交差するオブジェクトでは描画順が不正確になります。切り抜きには alphaTest を使うと、マテリアルを不透明のままにできるため、不透明パスで描画され、順序にかかわらず正しく表示されます。 - 見た目に合う最も低コストのマテリアルを選びます。Basic、Lambert、Phong、Standard、Physical の順です。
WebGPU と TSL
MeshStandardMaterial やその他の組み込みクラスは、WebGPURenderer でも変更なしで動作します。レンダラーが自動的にノードマテリアルへ変換するためです。ShaderMaterial、RawShaderMaterial、MeshDepthMaterial、MeshDistanceMaterial にはノード相当のものがなく、Material "..." is not compatible とログに出力されます。カスタムシェーディングには、three/webgpu のノードマテリアルクラスと three/tsl の TSL ノードを使用してください。これらは WebGPURenderer を対象としています。WebGLRenderer で描画するには、アドオンの WebGLNodesHandler(three/addons/tsl/WebGLNodesHandler.js)を介して renderer.setNodesHandler() に渡す必要があります。これは移行支援機能であり、VSM シャドウ、MRT、トランスミッション、WebGPU のポストプロセッシングスタックには対応していません。
import * as THREE from "three/webgpu";
const renderer = new THREE.WebGPURenderer({ antialias: true });
await renderer.init(); // before any other use of the renderer
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
const scene = new THREE.Scene();
scene.background = new THREE.Color(0x111111); // the WebGPU canvas is transparent by default
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 100);
camera.position.set(0, 0, 3);
function animate() {
renderer.render(scene, camera);
}
renderer.setAnimationLoop(animate);
import * as THREE from "three/webgpu";
import { texture, mix, color, float, time, positionLocal, normalLocal, sin } from "three/tsl";
// Unlit: the node equivalent of a color ShaderMaterial
const unlit = new THREE.MeshBasicNodeMaterial();
unlit.colorNode = mix(color(0x0066ff), color(0xff0066), sin(time.mul(0.5)).mul(0.5).add(0.5));
// Lit: node slots replace the fixed properties; needs lights or scene.environment
const map = await new THREE.TextureLoader().loadAsync("color.jpg");
map.colorSpace = THREE.SRGBColorSpace;
const lit = new THREE.MeshStandardNodeMaterial();
lit.colorNode = texture(map);
lit.roughnessNode = float(0.2);
// Vertex displacement on positionLocal, which already carries skinning, morphs, instancing
const shell = new THREE.MeshStandardNodeMaterial();
shell.positionNode = positionLocal.add(normalLocal.mul(sin(positionLocal.y.mul(6))).mul(0.05));
import * as THREE from "three/webgpu";
import { instancedBufferAttribute } from "three/tsl";
// The WebGPU backend draws Points at 1 px whatever the size; draw larger points as quads
const positions = new THREE.InstancedBufferAttribute(new Float32Array(1500), 3); // fill with x, y, z per point
const points = new THREE.Sprite(
new THREE.PointsNodeMaterial({ positionNode: instancedBufferAttribute(positions), size: 4, sizeAttenuation: false }) // 4 px squares
);
points.count = 500; points.frustumCulled = false; // one quad per point; culling would test only a 0.7-unit sphere at the sprite origin
scene.add(points);
よくある間違い
geometry.setAttribute("uv2", geometry.attributes.uv)→const material = new THREE.MeshStandardMaterial({ aoMap });:aoMap はaoMap.channelで選択した属性をサンプリングします。デフォルトは 0(uv)のため、追加の属性は不要です。uv2はaoMap.channel = 2の場合にのみ読み込まれ、別途アンラップした UV はaoMap.channel = 1としてuv1に格納します。new RGBELoader()→new HDRLoader():HDRLoader は r180 で RGBELoader から名称が変更されました。RGBELoader は非推奨ですが、警告が表示されるものの引き続き読み込めます。import HDRLoader from "three/addons/loaders/HDRLoader.js"を使用してください。"three/examples/jsm/loaders/HDRLoader.js"→"three/addons/loaders/HDRLoader.js":ブラウザーのインポートマップはthree/addons/を examples/jsm/ にマッピングしており、three/examples/のキーは定義していないため、examples パスでは読み込みに失敗します。material.blending = THREE.MultiplyBlending;→material.blending = THREE.MultiplyBlending; material.premultipliedAlpha = true;:乗算ブレンディングと減算ブレンディングにはプリマルチプライドアルファが必要です。設定しないと、レンダラーはエラーを記録し、ブレンド関数を設定しません。material.stencilMask = 0xff;→material.stencilFuncMask = 0xff; material.stencilWriteMask = 0xff;:stencilMaskは存在しません。代入しても未使用のフィールドが作成されるだけです。new THREE.WebGLRenderer({ antialias: true })→new THREE.WebGLRenderer({ antialias: true, stencil: true }):ステンシルバッファはデフォルトで無効のため、有効にしないとマテリアルのステンシル設定は無視されます。material.envMapIntensity = 0.5;→scene.environmentIntensity = 0.5;:scene.environment を暗くするには、scene プロパティを使用してください。envMapIntensity が減衰させるのは、マテリアル独自の envMap のみです。material.uniforms.time.value = clock.getElapsedTime();→material.uniforms.time.value = timer.getElapsed();:Clock は r183 で非推奨になりました。THREE.Timer を作成し、timer.connect(document) を一度呼び出してから、ループの最初に引数なしで timer.update() を呼び出してください。new THREE.ShaderMaterial({ glslVersion: THREE.GLSL3, fragmentShader })→new THREE.ShaderMaterial({ fragmentShader }):ShaderMaterial はすでに GLSL ES 3.00 としてコンパイルされるため、glslVersion を設定しなくてもtexture()を使用できます。一方、GLSL3 はgl_FragColorのエイリアスを削除するため、これに書き込むシェーダーはコンパイルに失敗します。uniforms: { modelViewMatrix: { value: new THREE.Matrix4() } }→uniform mat4 modelViewMatrix;:組み込み行列は RawShaderMaterial のシェーダーソース内で宣言してください。同名の uniforms エントリーは、描画ごとに上書きされる(modelMatrix、modelViewMatrix、normalMatrix)か、カメラの値を置き換えます(projectionMatrix、viewMatrix、cameraPosition)。new THREE.LineBasicMaterial({ linewidth: 5 })→new Line2(new LineGeometry().setPositions([-1, 0, 0, 1, 0, 0]), new LineMaterial({ linewidth: 5 })):WebGLRenderer は線プリミティブを常に 1 px で描画します。Line2 には BufferGeometry ではなく LineGeometry が必要です。また、3 つとも three/addons/lines/ からインポートします(WebGPURenderer では、Line2 は Line2NodeMaterial とともに three/addons/lines/webgpu/Line2.js からインポートします)。new THREE.ShaderMaterial({ vertexShader, fragmentShader })→new THREE.MeshBasicNodeMaterial():WebGPURenderer ではノードマテリアルと TSL を使用してください。ShaderMaterial と RawShaderMaterial にはノード相当のものがなく、「is not compatible」というエラーが記録されます。import { texture } from "three/nodes";→import { texture } from "three/tsl";:three/nodesは存在しません。ノードマテリアルはthree/webgpuから、TSL 関数はthree/tslからインポートします。import * as THREE from "three"; const m = new THREE.MeshStandardNodeMaterial();→import * as THREE from "three/webgpu"; const m = new THREE.MeshStandardNodeMaterial();:ノードマテリアルは three/webgpu からのみエクスポートされ、WebGPURenderer を対象としています。new THREE.PointsMaterial({ size: 5 })→new THREE.Sprite(new THREE.PointsNodeMaterial({ positionNode: instancedBufferAttribute(positions) })):WebGPU バックエンドでは、サイズにかかわらず Points は 1 px で描画されます。sprite.count を点の数に設定してください。material.positionNode = positionGeometry.add(offset);→material.positionNode = positionLocal.add(offset);:positionLocal にはスキニング、モーフターゲット、バッチング、インスタンシングが反映されます。positionGeometry はポーズ適用前の生の属性です。map.encoding = THREE.sRGBEncoding;→map.colorSpace = THREE.SRGBColorSpace;:encodingとsRGBEncodingはすでに存在しないため、元の行は何もせず、カラーマップの色が薄く表示されます。const m = new THREE.MeshStandardNodeMaterial(); m.colorNode = color(0xff0000);→const m = new THREE.MeshBasicNodeMaterial(); m.colorNode = color(0xff0000);:MeshStandardNodeMaterial はライティングの影響を受け、ライトまたは環境がないと黒く描画されます。ライティングを必要としない効果には MeshBasicNodeMaterial を使用してください。new THREE.ShaderMaterial({ extensions: { derivatives: true }, fragmentShader })→new THREE.ShaderMaterial({ fragmentShader }):GLSL ES 3.00 ではdFdx、gl_FragDepth、textureLodが組み込みでサポートされるため、WebGL1 の拡張フラグは何も行いません。
関連項目
threejs-textures- 読み込み、色空間、フィルター、チャンネルの詳細threejs-shaders- WebGLRenderer における GLSL の作成、シェーダーチャンク、デバッグthreejs-lighting- ライト、影、およびそれらとマテリアルとの相互作用