NIJIBOX

three.jsを触ってみた(その2) 〜 3Dモデルを描画してみるの巻 〜

更新日 2019.10.24
three.jsを触ってみた(その2) 〜 3Dモデルを描画してみるの巻 〜

[markdown]

前回([three.jsを触ってみた](https://creatorsblog.nijibox.jp/hello-threejs/))はthree.jsでhello world!をしてみたわけなんですが、今回は3Dらしく、
**3Dモデルを表示させたいと思います!**

3Dといえばやっぱり、3Dモデルを表示させて動かすに限りますよね!

こんな感じで!

## three.jsで対応可能な3Dデータ
まずはどんな、ファイルフォーマットの3Dデータが利用可能か見てみましょう、
three.jsがサポートしているファイルフォーマットはこちらです!

`JSON`, `OBJおよびMTL`, ` Collada`、 `STL`, `CTM`, `VTK`, `AWD`, `Assimp`, `VRML`, `Babylon`, `PDM`, `PLY`

なんかいっぱいありますね!ほとんど知らない!こんなにあるんか…ほとんど知らないぞ!?

OBJだけかろうじて知ってるような気がする…。
なんだか世にある3Dフォーマット全部かかってこい! 的な勢いありますね。ちゃんと調べてないんですが…。
なんとなく調べて見た感じ、医療用からゲームまで幅広く対応しているようです。

そして、これに加えてニコニコ動画などでよく見るMMD形式(pmd,pmx等)も使えるという。
なるほど…。

1点だけJSON(3D扱う形式ではない)が紛れているのは、three.jsに独自にJSONのフォーマットがあるためらしいです。
JSON形式で読み込みを行う場合は、3DデータをJSON形式に変換する必要があるんですが、three.js公式では、Blender(オープンソースの3DCGソフト)を利用して書き出す方法が紹介されています。

ちなみに、今回表示させるのはOBJ形式の3Dデータでいきたいと思います。
なぜなら、`もっとも広く採用させている3Dファイルフォーマットのひとつ`だから!
**OBJとMTLの説明**

OBJはもともとWavefront Technologiesによって開発された単純な3Dフォーマット。
もっとも広く採用されている3Dファイルフォーマットのひとつで、オブジェクトの形状を定義するために利用できる。

MTLはOBJに付随するフォーマット。MTLファイルではOBJファイル内のオブジェクトのマテリアルを指定する。three.jsにはOBJExporter.jsという独自のOBJエクスポーターもあり、three.jsのモデルをOBJ形式で エクスポートしたい時に利用できる。
初めてのThree.js 第2版――WebGLのためのJavaScript 3Dライブラリより引用

## 3Dデータを用意する
どんなデータを用意すれば良いか大体わかったので、次は3Dデータを準備します。
どうやって用意するかというと、以下の方法があります。

1. 自分で作る
2. プロに作ってもらう
3. 買う

今回は一番楽で手っ取り早い方法 **買う(無料のものを)** でいきたいと思います!

データはこちらのサイトからいただくことにしました。



https://tf3dm.com/

とりあえず.objが付いているやつをダウンロードすれば、そのまま表示できるってことですね!

## OBJファイルを表示してみる
表示するのはこちら! マグロです。
(会社の住所が築地市場の川向かいということで)

ワクワクです。

threejsのexamplesのobj/mtlを参考にとりあえず入れてみました。

あれ? なんだかおかしい…


原因わからず調べていると、
ズームをしてやっと極小のマグロを見つけることができました。

**なんで!? このマグロ、やたらちっさいぞ!!**

## サイズを調整する
落としてきた3Dファイルのサイズがかなり小さかったみたいなので、
こんな感じでサイズを調整してあげる必要があるみたいです。

“` javascript
// OBJ MTLの読み込み
var mtlLoader = new THREE.MTLLoader();
mtlLoader.setPath( ‘./tuna/’ ); // this/is/obj/path/
mtlLoader.load( ‘tuna.mtl’, function( materials ) {
materials.preload();
var objLoader = new THREE.OBJLoader();
objLoader.setMaterials( materials );
objLoader.setPath( ‘./tuna/’ ); // this/is/obj/path/
objLoader.load( ‘tuna.obj’, function ( object ) {
objmodel = object.clone();
objmodel.scale.set(100, 100, 100); // 縮尺の初期化
objmodel.rotation.set(0, 0, 0); // 角度の初期化
objmodel.position.set(0, 0, 0); // 位置の初期化

// objをObject3Dで包む
obj = new THREE.Object3D();
obj.add(objmodel);

scene.add(obj); // sceneに追加
}, onProgress, onError );
});
“`

objectのスケールを(1,1,1)にするために、(後々アニメーションするときとかに多分こっちの方が便利なので)
`一旦あらたなオブジェクトを作成` → `スケールを調整` → `新しいobject3Dでまとめる`
的なことをしてあげています。
3Dデータ読み込む場合、結構こういうことありそうなので、
モデルが表示されてない!?とかなった時はサイズがすごく小さいorすごく大きいみたいなことも気にしてあげた方がいいかもしれません。

## 次はテクスチャが表示されない
適当なスケールでの表示には成功したんですが、
続いて、テクスチャが表示されない壁にぶち当たりました。
(ダウンロードしたフォルダにMTLファイルもテクスチャ用らしきTIFファイルも入っていたのに)

しばらくウンウン唸っていたところ、なんとなく原因がわかりました。
原因は、MTLファイルがよろしくなかったらしく、MTLとOBJのセットを新たに書き出し直すことでなんとか解決しました。

MTLの作成ではこちら(Photoshopで3DのOBJファイルからMTLファイルを作成する方法 | Qiita記事)を参考にしています。
なんとPhotoshopを用いてMTLとOBJファイルを出力します。(そういえば、PSDって3D対応してましたね。)


こんな感じの工程を経て、テクスチャ書き出します。詳しくは上の参考リンクでお願いしますm(_ _ )m

## テクスチャ貼れたけど…
なんとかテクスチャ貼り付けるのには成功したんですが、


結局、正しいテクスチャデータがなかったので、こんな有様です。
**(多分マグロではない)**

本来モデルデータ作成する際にはテクスチャデータも一緒に作成するはずなので、
正しい手順、正しいデータの場合ならば、「テクスチャが変!?」「あれ? MTLがおかしい!?」みたいな工程はないはずです。

ちなみに、他の3Dモデル(MTLなし、テクスチャあり)ではちゃんと描画できました!(冒頭に出てきた牛です)

## テクスチャは諦めて現状できることで、それっぽいコンテンツを作る。
(一応…)モデルの描画には成功したので、今回表示したモデルを使って、それっぽいものを作りました。

マグロっぽい魚が、海を気持ちよく泳いでますね〜
アニメーションは三角関数を無双してそれっぽーくしています。
ビジュアルプログラミングには、三角関数がつきものですよね!

# まとめ
やっぱり、three.jsは楽しいですね、
自分で、モデルまで作れたらまた楽しいんでしょうが、
そうすっと、おそらく個人的に時間が足りなくなるので、モデルに関しては、他の人に用意してもらったものを使ってアニメーションとかインタラクションを充実させたいものです。

そしてこの記事を、しれっとシリーズ化して行きます…。

[/markdown]