mcpField
T
threejs-materials-lighting

threejs-materials-lighting

github.com/gamedev-skillsクリエイティブ・メディア5.4k6.2k 回インストール1 日前に更新
リポジトリ

threejs-materials-lighting について

three.js のシーン開発やトラブルシューティング向けに、マテリアル、照明、シャドウ、イメージベースドライティングの設定を扱うスキルです。r186 を対象に検証されています。

主な機能

  1. 01PBR・非照明・デバッグ用マテリアルの選択
  2. 02フィルライトとキーライトの組み合わせ
  3. 03シャドウの有効化と調整
  4. 04環境マップ反射の追加
  5. 05PBR テクスチャの色空間設定

活用シーン

  1. 01黒や平坦に見えるメッシュの原因調査
  2. 02シーンのシャドウ設定
  3. 03HDR 環境からの反射追加

インストール

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

$npx skills add https://github.com/gamedev-skills/awesome-gamedev-agent-skills --skill threejs-materials-lighting

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

同梱ファイルreferences/materials-lights-table.md

詳細

three.js のマテリアルとライティング

three.js のサーフェスを適切に表示するには、目的に合ったマテリアルを選び、シーンにライトを当て、シャドウを有効にし、イメージベースドライティングを追加します。パターンは r186 を対象としており、r186 で検証済みです(ライティングは r155 以降、デフォルトで物理ベースです)。

使用する場面

  • メッシュが黒く、または平坦に表示される場合、マテリアルを選ぶ場合、ライトを追加する場合、シャドウを有効にする場合、環境マップの反射(IBL)を設定する場合に使用します。
  • MeshStandardMaterial、DirectionalLight などを構築するコードや、renderer.shadowMap.enabled または scene.environment を設定するコードを扱う場合に使用します。

使用しない場面: レンダラー/カメラ/ループ → threejs-scene-setup。モデルの読み込み(このトピックでは、その PBR マテリアルを補完します)→ threejs-gltf-loading。カスタム GLSL/ShaderMaterial は別のトピックです。移植性の高い概念については shader-programming を参照してください。

基本的なワークフロー

  1. 必要に応じてマテリアルを選びます。 リアリティを重視するなら MeshStandardMaterial(PBR:roughness、metalness を使用し、ライト/IBL に反応します)、クリアコート/透過には MeshPhysicalMaterial、UI/フラット表示には MeshBasicMaterial(アンリットで、ライトを無視します)、デバッグには MeshNormalMaterial/MeshDepthMaterial を使用します。
  2. ライトを追加します。追加しないと何も表示されません。 ライトを使うマテリアルには、光源および/または scene.environment が必要です。柔らかな補助光(AmbientLight/HemisphereLight)と、キーライトの DirectionalLight を組み合わせます。
  3. ライトの強度に注意します。 r155 以降、ライティングは物理ベースです。現行の強度は古いチュートリアルより高くなっています(キーライトの DirectionalLight は約 1~3)。
  4. 3か所でシャドウを有効にします。 renderer.shadowMap.enabled = true、ライトの castShadow = true、各メッシュの castShadow/receiveShadow を設定します。その後、ライトのシャドウカメラをシーンに合わせます。
  5. 自然な反射には環境マップを使用します。 正距円筒図法または PMREM 処理済みのテクスチャを scene.environment に割り当てると、PBR マテリアルが自動的に使用します。
  6. 実際のライティングで確認します — サーフェスがキーライトに反応すること(ハイライトが移動すること)、シャドウが想定した場所に落ちること、反射が自然に見えることを確認します。

パターン

1. 3灯のセットアップで PBR マテリアルを使用
import * as THREE from 'three';

const material = new THREE.MeshStandardMaterial({
  color: 0xcc4444,
  roughness: 0.5,     // 0 = mirror, 1 = fully matte
  metalness: 0.0,     // 0 = dielectric (plastic/wood), 1 = metal
});
const mesh = new THREE.Mesh(new THREE.SphereGeometry(1, 32, 16), material);
scene.add(mesh);

// Soft sky/ground fill + a directional key light.
scene.add(new THREE.HemisphereLight(0xbbddff, 0x443322, 1.0)); // sky, ground, intensity
const key = new THREE.DirectionalLight(0xffffff, 2.5);
key.position.set(5, 10, 7);
scene.add(key);
2. アンリットマテリアル(ライト不要)
// MeshBasicMaterial ignores lights — for flat color, UI, or sprites/labels.
const flat = new THREE.MeshBasicMaterial({ color: 0x44aa88 });
// A textured color map should be tagged sRGB so colors aren't washed out:
const tex = new THREE.TextureLoader().load('assets/logo.png');
tex.colorSpace = THREE.SRGBColorSpace;
const logo = new THREE.MeshBasicMaterial({ map: tex, transparent: true });
3. シャドウ(必須の3つの設定とカメラの調整)
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFShadowMap;         // soft by default since r182

const sun = new THREE.DirectionalLight(0xffffff, 3);
sun.position.set(8, 12, 6);
sun.castShadow = true;
sun.shadow.mapSize.set(2048, 2048);                   // default 512; raise for crisp
// DirectionalLight uses an OrthographicCamera — fit it tightly to the scene:
const cam = sun.shadow.camera;
cam.near = 1; cam.far = 40;
cam.left = -15; cam.right = 15; cam.top = 15; cam.bottom = -15;
scene.add(sun);

mesh.castShadow = true;
ground.receiveShadow = true;                          // a plane to catch the shadow
4. マテリアルに PBR テクスチャを使用
const loader = new THREE.TextureLoader();
const colorMap = loader.load('assets/brick_color.jpg');
colorMap.colorSpace = THREE.SRGBColorSpace;           // color maps are sRGB
const normalMap = loader.load('assets/brick_normal.jpg'); // data maps stay linear
const roughMap  = loader.load('assets/brick_rough.jpg');

const brick = new THREE.MeshStandardMaterial({
  map: colorMap,
  normalMap,
  roughnessMap: roughMap,
  metalness: 0,
});
5. HDR 環境を使ったイメージベースドライティング
import { HDRLoader } from 'three/addons/loaders/HDRLoader.js'; // RGBELoader before r180

new HDRLoader().load('assets/studio.hdr', (hdr) => {
  hdr.mapping = THREE.EquirectangularReflectionMapping;
  scene.environment = hdr;     // lights + reflects all PBR materials
  scene.background = hdr;       // optional: show it as the backdrop
});
// Optional cinematic tone curve:
renderer.toneMapping = THREE.ACESFilmicToneMapping;
renderer.toneMappingExposure = 1.0;

注意点

  • メッシュが真っ黒になる → ライトも scene.environment もない状態で、ライトを使うマテリアルを使用しています。ライトまたは環境マップを追加します。ジオメトリを確認するには、一時的に MeshBasicMaterial/MeshNormalMaterial に切り替えます。
  • ライトがあるのにシーンが暗すぎる → 古いチュートリアルの強度を使っています。r155 以降は物理ベースなので、強度を上げる(キーライトは約 2~3)か、環境マップを追加します。
  • シャドウが表示されない → 必須の3つの設定(renderer.shadowMap.enabled、light.castShadow、メッシュの castShadow/receiveShadow)のいずれかが不足しています。
  • シャドウが途切れる、または粗い → DirectionalLight の正投影 shadow.camera フラスタムが大きすぎる、小さすぎる、またはシーン全体をカバーしていません。left/right/top/bottom/near/far を調整して範囲を絞り、shadow.mapSize を大きくします。new THREE.CameraHelper(light.shadow.camera) で可視化できます。
  • シャドウのアクネ/ピーター・パンニング → light.shadow.bias(小さな負の値)と light.shadow.normalBias を調整します。
  • 色が白っぽい、または明るすぎる → カラー(アルベド)テクスチャには texture.colorSpace = THREE.SRGBColorSpace が必要です。法線/ラフネス/メタルネスマップはリニアのままにする必要があるため、NoColorSpace のままにします。
  • PointLight のシャドウでパフォーマンスが大幅に低下する → ポイントライトはシーンを6回レンダリングします(キューブマップ)。シャドウを投影する DirectionalLight を1つ使い、その他の場所では軽量な代替手段を使用してください。

参考資料

  • マテリアルの早見表(どの見た目にどの Mesh*Material を使うか)、ライトの種類とパラメーター/単位、透明度と alphaTest の描画順序、HDR ファイルなしで IBL を実現する PMREMGenerator/RoomEnvironment の方法については、references/materials-lights-table.md を参照してください。

関連スキル

  • threejs-scene-setup — レンダラー、カメラ、ループ(shadowMap、トーンマッピングを設定します)。
  • threejs-gltf-loading — このスキルで調整するPBRマテリアルをモデルに適用します。
  • shader-programming — カスタムシェーダーエフェクト(エンジンに依存しない概念)。

コメント