はじめに

Three.jsでモデルファイル「gLTF」を読み込んだ際に、または色空間の不一致でモデルが常に明るく表示されたり、逆に暗いままで適切に変わらない問題の修正方法が分かったので、メモも含めて記事にしておきます。

結論から言うと、Blenderでマテリアルの設定を修正する事で解決できます。

問題の原因

1. 色空間の不一致

Blenderで作成したモデルは通常sRGB色空間で作成されますが、Three.jsではLinear色空間でレンダリングされます。この違いが、モデルが意図した通りに表示されない原因となります。

2. Emission 設定の強度

BlenderでEmission(自発光)の強度が高いと、モデルが自発光しているように見え、シーン内の他の光源が影響を与えず、常に明るく表示されます。反対に、Emissionを完全にゼロにするとモデルが暗くなりすぎてしまいます。

3. ライティング不足

シーンに適切なライトが配置されていない場合、モデルが明るく見えなくなります。特に、AmbientLightやDirectionalLightの設定が不足していると、モデルが真っ暗に表示されます。

4. Metallic と Roughness の設定(Blender側)

Metallic と Roughness の設定が適切でないと、モデルが光の反射を適切に受けないことがあります。特に、Blender側で Metallicが0の場合、金属的な反射がないため、モデルの光沢感が失われ、逆に0に設定しすぎると光を反射しない非金属的な質感になります。Roughnessが0の場合、表面が非常に滑らかで光が強く反射し、逆に高すぎると光がぼやけた反射となり、表現が不自然になることがあります。

修正方法

1. Three.jsでの色空間設定

Three.jsのレンダラーにoutputEncodingプロパティを設定して、正しい色空間で出力するようにします。

const renderer = new THREE.WebGLRenderer();
renderer.outputEncoding = THREE.sRGBEncoding; // 出力色空間をsRGBに設定
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

これにより、レンダリング結果がLinearからsRGBに適切に変換され、色空間の不一致を解消できます。

2. Emission 設定の確認

BlenderでEmissionの強度が原因で明るさが変わらない場合、Emissionの強度を調整するか、完全に無効にします。

  1. Blenderで、Principled BSDFシェーダーを使用している場合、Emissionの強度を0に設定するか、Emission自体を削除します。
  2. エクスポートする前に、Emissionが有効でないことを確認します。

3. シーンにライトを追加

Three.jsでのモデルが暗いままで表示される場合、適切なライトが配置されていないことが原因です。AmbientLightやDirectionalLightを追加して、シーン全体を照らします。

// シーンにライトを追加
const ambientLight = new THREE.AmbientLight(0x404040, 1); // 軽い光
scene.add(ambientLight);

const directionalLight = new THREE.DirectionalLight(0xffffff, 1); // 方向性のある光
directionalLight.position.set(10, 10, 10).normalize();
scene.add(directionalLight);

これにより、シーン全体が均等に照らされ、暗い表示が改善されます。

4. Metallic と Roughnessの設定(Blender側)

BlenderでMetallicとRoughnessを調整することで、光の反射具合を制御できます。

  • Metallicを0に設定した場合、モデルは非金属的な質感になります。金属的な反射を加えたい場合は、Metallicを1に設定します。
  • Roughnessは反射の拡散具合を決めます。0だと非常に鋭い反射になり、1に近づけると表面が粗く、ぼやけた反射になります。

Blenderでこれらを調整する方法は以下の通りです:

  1. Principled BSDFシェーダーのMetallicとRoughnessを調整します。
  2. Metallicを金属感のある質感にしたい場合は1に、非金属的な質感にしたい場合は0に設定します。
  3. Roughnessは0から1の間で設定し、表面の反射具合を調整します。
// BlenderのPrincipled BSDFシェーダー設定例
const material = new THREE.MeshStandardMaterial({
  color: 0xaaaaaa,
  roughness: 0.5,  // 反射のぼやけ具合
  metallic: 0.2    // 金属的な反射具合
});

5. テクスチャの色空間の設定

BlenderでBase Colorに使用しているテクスチャがLinear色空間で作成されている場合、それをsRGBに変更する必要があります。BlenderのImage TextureノードのColor Space設定を確認し、適切に設定します。

6. エクスポート設定の確認

BlenderからThree.jsにエクスポートする際、GLTF(またはGLB)形式でエクスポートします。エクスポート時にEmissionやBase Colorのテクスチャが正しくエクスポートされるように設定します。

  1. Blenderのエクスポート設定で、IncludeセクションにてTexturesやMaterialsが適切にエクスポートされるように設定します。
  2. EmissionやBase Colorの設定がLinearからsRGBに適切にエクスポートされているか確認します。

まとめ

  1. Three.jsの色空間設定: renderer.outputEncoding = THREE.sRGBEncoding で色空間の不一致を解消します。
  2. Blenderでの Emission 設定: Emission が強すぎる場合、 Strength を 0 に設定するか削除します。
  3. シーンにライトを追加: 適切な AmbientLight や DirectionalLight をシーンに追加し、モデルが適切に照らされるようにします。
  4. Metallic と Roughness の設定: Blender側で光沢感や反射具合を調整します。
  5. テクスチャの色空間設定: Blenderで使用するテクスチャの色空間を sRGB に変更します。
  6. エクスポート設定の確認: BlenderからGLTF/GLB形式でエクスポートする際に、 Emission や Base Color が正しくエクスポートされるように確認します。

これらの手順を試すことで、モデルが意図した通りに表示されるようになるはずです。