🎨

Three.jsでglTFモデルをUnlitで表示したいとき

2024/02/07に公開

Blenderなどで書き出されたモデルは基本的に、Three.jsでロードされた際にMeshStandardMaterialが与えられる
(陰影や質感のある通常のPBRマテリアル(Principal BSDF)と互換性がある)
しかし陰影のないMeshBasicMaterialを使いたいシーンも多々ある

Three.js上で表示するglTFモデルに陰影を与えたくない場合、選択肢は2つ

Three.jsで読み込み後にモデルのマテリアルを差し替える

model.traverse((child) => {
     if ( ! child.isMesh ) return;
     var prevMaterial = child.material;
     child.material = new MeshPhongMaterial();
     MeshBasicMaterial.prototype.copy.call( child.material, prevMaterial );
});

https://stackoverflow.com/questions/61717393/how-do-i-convert-all-materials-in-a-loaded-gltf-from-mesh-basic-to-mesh-phong

glTFモデルをUnlitモデルとして書き出す

glTFモデルの書き出し時にglTF拡張機能のKHR_materials_unlitを使用するよう設定する。
この拡張機能が設定されたマテリアルはThree.jsでのロード時にMeshBasicMaterialが与えられる

Blenderから書き出す際に設定する

BlenderのglTF Exporterは書き出し時にマテリアルのノードを見て自動で通常のPBRマテリアルを設定するかShadeless (KHR_materials_unlit) を設定するかを切り替える
https://docs.blender.org/manual/ja/dev/addons/import_export/scene_gltf2.html#exported-materials


基本方針としては以下のようにする

  • マテリアル出力にシェーダーミックスを繋ぎ、ライトパスを係数に、テクスチャ画像をシェーダー2に繋ぐ。
  • BSDF プリンシパルノードは削除する(どこにも繋がってなくても、存在するだけでPBRで書き出されてしまう)

これによってglTF Exporterでの書き出し時に自動でKHR_materials_unlitが割り当てられる
gltf-viewerに放り込むと、自動でMeshBasicMaterialが割り当てられているのがわかる

この方法なら、同一モデル内でもマテリアルの設定を変えればUnlitとPBRのメッシュを混在できる

gltf-transformでモデルを変換する

別の方法として、コマンドラインツールのgltf-transformを使ってモデルのマテリアルをunlitに変えられる
https://gltf-transform.dev/cli

$ gltf-transform unlit test.glb test-unlit.glb

この方法は元のモデルを開いてマテリアルに手を加える必要がないのでお手軽
一方で全てのマテリアルが自動変換されるため、Blenderのようにプレビューで細かい調節をすることはできない

Discussion