【three.js】GLTF loaderで読み込んだモデルを透明にしたい
はじめに
three.jsでgltfモデルを読み込んで、そのモデルを透明にしたかったのです。
モデルを透明にするにはmaterialのプロパティを変更しなければならないのですが、細かいところで躓いてしまったのでメモです。
失敗例
const gltfLoader = new THREE.GLTFLoader();
gltfLoader.load('XXX.glb', (gltf) => {
const model = gltf.scene; //モデルを取得
model.material.transparent = true; //マテリアルの設定変更
model.material.opacity = 0.5; //マテリアルの設定変更
scene.add(gltf.scene);
})
最初こうやっていたのですが、これだとmodel.material
はundefined
になります。
それもそのはず、gltf.scene
はSceneオブジェクトのインスタンスです。
materialにアクセスできるMeshではありません!
シーンに追加するときにscene.add(gltf.scene)
ってやるので、てっきりMeshかと勘違いしてました。(そもそもgltf.scene
って書いてあるじゃん。。)
gltf.sceneの構造ですが、ロードしたgltf.scene自体は一個の大きな親で、その配下にたくさんの要素がある構造のようです。
なので解決策としては、gltf.sceneを構成している要素に含まれているMeshにアクセスすればよい、ということになります。
sceneの子要素にアクセスするためには、traverseを使用します。
成功例
const gltfLoader = new THREE.GLTFLoader();
gltfLoader.load('XXX.glb', (gltf) => {
const model = gltf.scene; //モデルを取得
model.traverse((object) => { //モデルの構成要素をforEach的に走査
if(object.isMesh) { //その構成要素がメッシュだったら
object.material.trasparent = true;
object.material.opacity = 0.5;
}
});
scene.add(gltf.scene);
})
これでMeshにアクセスして、materialを透明にできました!
※3Dモデルの出典( https://poly.google.com/view/1L9oJAw6nY2 )
めでたし。
おまけ:Webで3Dモデルを使用する際の注意点
おまけですが、Webで3Dモデルを使用する際はやっぱり軽くないとダメですね。
特にモバイルでも見せたい場合。あまりにも重いと読み込み時点でブラウザがクラッシュします。
わかりやすい目安をWebARのプラットフォームである8thwallさんが示してくれていて、
- ファイルサイズが小さくなる、「.glb」形式ファイルが望ましい
- 一つのモデルのファイルサイズは10MBまで
が良いようです。
※glbはgltfのバイナリファイルで、GLTF Loaderで読み込み可能です。
gltfを持っていて、glbに変換したい方は「 https://sbtron.github.io/makeglb/ 」
こちらが便利!
また、objしか持っていない方も、gltfにはオンラインで変換できるサイトが結構あります。
Discussion