Three.js Advent Calendar 2019 2日目
最近、Threejs触っていてちょっとツマったとき、ググっても日本語の記事は見かけなかったのでメモとして残します。
やりたかったこと
3D空間上の任意の位置にオブジェクトをたくさん置きたい
↓
jsで実装して、最終的な見え方をその都度確認するのはめんどくさい
↓
DCCツール上で見栄えを確認しながら配置してもらい、それをMeshとかにしてfbxとかで書き出し、頂点座標を取得して配置すれば良いんじゃね。
こんな流れでした。
ツマったこと
頂点座標自体は BufferGeometry 経由で簡単に取得できます。
geometry.attributes.position.array //頂点座標が配列に格納されている
簡単な例として、Blenderから書き出した平面四角(Plane)のfbxデータの頂点座標を上記のように取得して、各座標に半透明のCubeを配置してみました。
実際に動作するサンプルはこちら↓
http://393.bz/threejs/sample/webgl_loader_fbx_not_merge.html
右上と左下のCubeの色が濃くなっているのが確認できると思います。
これはPlaneを構成してる頂点は一見4点と思いきや、実際は6点であり、右上と左下が重複しているせいです。
(このPlaneは、上図の緑色の線で構成された三角ポリゴンとピンク色の線で構成された三角ポリゴンで作られていたためです)
解決方法
座標が全く一緒な頂点を除外すればよいだけなので、自力で実装しても良いのですが、きっとすでにイイ感じの実装がすでにあるはず、、、とググりまくってるとちゃんと公式にありました。
BufferGeometryUtils.mergeVertices
// geometryを引数で渡すと、重複した頂点を除外したgeomeryを返してくれる
const mergeGeometry = BufferGeometryUtils.mergeVertices(child.geometry);
重複した頂点を除外したgeometryから頂点情報を取得して半透明のCubeを配置する
実際に動作するサンプルはこちら↓
http://393.bz/threejs/sample/webgl_loader_fbx_merge.html
重複したメッシュが消えました。
まとめ
半透明で配置することなんてあんまりないと思うので重複してることに気づかないことも多く、気づかないなら問題ないような気がしますが、今回気づいたのは、半透明かつ、Blendingを加算にしたら、特定のオブジェクトだけやけに白くなってしまったので気づくことができました。