jThreeとは
jThreeはオブジェクトをタグの形で記述できるWebGLのライブラリです(リンク:jThree)。オブジェクトの生成、マテリアル・テクスチャの割り当てをタグで書くことができて、オブジェクトを出してみるあたりまでであれば、JavaScriptの知識がなくてもWebで3Dを体験することができます。簡単にMMDモデルを踊らせることができたり、最近では立体音響に対応したり、ハコスコ等で見られる形式に対応していたりします。
名前の通り、スクリプトもjQueryの記法で書くことができる上、オブジェクトのクリックイベント等も同様にイベントハンドラ(on)で取得できるので非常に便利です。
jThreeの弱点
さて、jThreeの便利なところとか、どんなものか、ということは何度か書いたように思うので、今回は弱点に迫ってみたいなと思って書いています。jThreeの弱点といえば
- 公式ドキュメントがない
- 実行速度が遅い(らしい)
ですね。前者については有志ユーザによっていくつか作成が始まっているようで、対応が進んでいますが、後者は「らしい」という話を伺ったり、確かにそうだけど・・・という感じで、実際にどうなのか見てなかったなあと一昨日思いついたので少しやってみようかと思います。
実行環境
- Machine: MacBookAir(Mid 2011)
- Browser: Google Chrome(2014/12/17時点での最新版)
- SublimeServerでローカルサーバ環境をつくって実行
という構成でやっていきます。
PCが非力なのはご愛嬌です。
やってみること
three.jsで書いたものと、jThreeで書いたもので、どれくらい実行速度が違うのかを見てみたいと思います。とはいえ、実行結果をChrome Developer Toolsで確認してみるだけです。
###ゆるふわです。
ただし、 それぞれのライブラリで記述しやすい方法で、同じような動作になるよう実装しています。
例えば回転させるときに、
jThreeではよく使うanimateを使って
j3("#object").animate({rotate:...}, ...);
three.jsでは直接renderで三角関数で適当な値を生成して回転させています。
function render() {
requestAnimationFrame(render);
for(i = 0; i < count; i++) {
var randomValue = ...;
cube[i].position.x = Math.sin(randomValue) * posLength[i];
cube[i].position.z = Math.cos(randomValue) * posLength[i];
}
renderer.render(scene, camera);
controls.update();
stats.update();
}
という感じで書いてあります。
このあたりも速度に影響するでしょうし、いろいろな書き方があるんだとは思いますが、きっとそれぞれのライブラリを使うときはそれぞれに合った使い方をするはずなので、あえてこのままで。
方法
両者共に同じ大きさ(同じ条件でランダム生成した大きさ)、同じマテリアルの立方体を最大1000個描画して、それぞれ同じ軸に対して回転させます。具体的にはこんな感じです。このときの読み込み速度やCPU稼働、FPSの変化を見てみます。
ご注意事項
ご覧の通りですが、「厳密」な検証はしていません。結果もなんとなく比べる程度ですので、ご参考程度にとどめておいていただけると幸いです。
実行に際しても、極力状況が変化しないように、続けて実行した結果を掲載していますが、他のアプリケーションの動作状況を確認したり、両者共に完全にフェアなコードを書けているわけでもありません。ご了承くださいませ。
やってみた
three.js
jThree
まとめ
three.jsのほうは読み込みは2秒弱といったところでしょうか。FPSは39〜41を推移。jThreeは、やはりjQueryの部分はネックになっているのか、読み込みに約8秒とかかり気味ですが、FPSは同様に40程をキープ。GOMLの展開が大変な模様でしょうか。具体的にメソッド単位での比較となるともう少しちゃんと調べてみないと差が分からないかもしれません(コード読んだほうが早そう)。
ちなみに、この構成だとオブジェクトの数に関わらずページロードにかかる時間はおよそ350ms〜500msで、もちろんオブジェクトの数が減ればロードにかかる時間も短くなります。今回は極端に1000個出してみましたが、10個にすればthree.jsで350ms、jThreeで500ms程度でロード完了します。このあたりの差は、jThreeがサポートしているthree.js外の機能の分も表れているのかもしれません。
また、オブジェクト数を2000個としてみると、ロードに要する時間は
jThree : 約17000ms
three.js : 約3800ms
ともなるので、単純計算でそれぞれ、1オブジェクトあたりに要する時間は
jThree : 約8〜8.5ms
three.js : 約1.7ms
程度になっています。もちろん、初期化の段階で生成するだけでなく、ユーザの入力や、アプリケーションの状態に応じてなんらかのオブジェクトを生成しようとしても同様の処理時間がかかります。大量にオブジェクトの生成・破棄が必要になってくるものを作るときは留意しておきましょう。某弾幕ゲームみたいなものは苦しいかもしれませんね・・・。
もう少しメソッド単位での違いを拾えたら、「これ便利だけど乱用すると重いよ」みたいなのが共有できていいかなと思いますが、jThreeの解剖調査は追い追い…。jThreeではGOML内で定義したオブジェクトをiQueryのように(j3("mesh")のように)取得できますが、そのあたりの速度も気になりますね。
ということで、今回のまとめとしては、
jThreeは、three.jsで書くよりもスクリプト記述量は激減できる一方で、オブジェクト生成には5倍くらい時間がかかるかも
思いつきでやってみようと思ったのですが、これをちゃんと検証するのはなかなか骨が折れそうだと後に気がつきました。「こんなことやってみるといいよ!」とか助言いただけると幸いです!
以上、WebGL AdventCalendar Day18 でした!
リンクなど
jThree : http://jthree.jp
three.js : http://threejs.org