three.jsを「遅い」と思わせないデータの扱い方
- 29. MMDLoader.jsの、モデルデータの読み込みコードの魔改造
コレを・・
//83行目(ビルド後ファイル・ver r84時点)
THREE.MMDLoader.prototype.load = function ( modelUrl, vmdUrls, callback, onProgress, onError ) {
var scope = this;
this.loadModel( modelUrl, function ( mesh ) {
scope.loadVmds( vmdUrls, function ( vmd ) {
scope.pourVmdIntoModel( mesh, vmd );
callback( mesh );
}, onProgress, onError );
}, onProgress, onError );
};
シングルスレッドの限界に挑むデータロード
- 30. MMDLoader.jsの、モデルデータの読み込みコードの魔改造
こうじゃ
//83行目(ver r84時点)
THREE.MMDLoader.prototype.load = function ( modelUrl, vmdUrls, callback, onProgress, onError ) {
var scope = this;
this.loadModel( modelUrl, function ( mesh ) {
var modeLoadEnd= function (_mesh) {
scope.loadVmds( vmdUrls, function ( vmd ) {
scope.pourVmdIntoModel( _mesh, vmd );
callback(_mesh );
}, onProgress, onError );
};
setTimeout(modeLoadEnd( mesh ), 10);
}, onProgress, onError );
};
シングルスレッドの限界に挑むデータロード
Editor's Notes
- えーみなさま、はじめましてでございます。
- 大したことは言いません。どうぞご歓談メインで、聞き流していただければと思います。
そのかわりウルサクさせていただきます。
ということでライトニングトークのお題です。
- スリーJSを「遅い」と思わせないデータの扱い方 ということで、お話させていただきたいと思います。よろしくお願いします。
-- 30s
- 今さらお前は誰だ、ということでですね、申し遅れました。私、タムラと申します。スリーJSで、個人制作でゲームなんて作ってみました。個人制作です。ゲーム作りをプロでやってるわけじゃありません、大したお話はできません。
チョット時間が5分からはみ出ちゃうと思うんですけど、ちらっとどんなゲームか、30秒ほど動画でおみせします。 このゲーム、お世辞ではなく、Edgeが一番早いです。 はい、お粗末様でした。
- 本日の流れ。どうでもいいですね。多分この通りに喋りません。時間使っちゃったし。
1m
- えーそもそもスリーJsってなんぞや、ということなんですが、JavaScriptの3Dプログラム向けのライブラリです。さきほど豊島さんがスリーJsって言ってたのでちょっと安心しました。知名度ちゃんとありますね。
WebGLをラッピングして、使いやすくしてくれたものです。もちろんオープンソースです。すげえ!
- この辺は流しますね。 えー大体あります。ゲーム向けメソッド多いです。素敵!はい次。
- インポータも結構そろってます。MMD、動かせます。楽しいです。
- だいたいこんなかんじです。すりーJSなんて初めて聞いたし、細かく知りたーい、と思ってくださったら、ググってみてください。 はい。
1m15s
- 今日はですね、完成直前とか、配信を意識するとか、そういう最後の段階で詰まったときの、解決につながる、かもしれないお話をさせていただきます。
先ほどカシマさんからも、ブラウザゲーム復興だーなんてありましたが、そんなリリース前のお話です。
- すりーJSで根性だして、3Dゲームを完成させました! すごい!やりきった! サーバースペースを用意して、アップロードして公開するとしましょう。
- もーね、きっと明日の朝には、すごーい、たーのしー!のコメントでいっぱいだ!!ワクワクしますね。
って思うと、
- 大体の場合、こうなるんですね。
あーあ。コレダメなやつだ。かーらーの
- こうなるんですね。 何がいけなかったのでしょう?
1m45
- いまさらな話をさせていただきます。JavaScriptは、シングルスレッドです。何を今更です。みんな知ってるだろうと。
2m
- こちらに、3Dモデルデータを、ダウンロードして使えるようにするまでフローを書いてみました。
ご覧の通り、ダウンロードの後に、まずは 「 ローダー側での処理 」がありまして、 すりーJS用に頂点データとか何やらを変換します。
みんな書くのは最後のコールバックのところだけ。 でも、その前にも動いてる処理がある、そのことをちょっと思い出しましょう。
2m30s
- そうなんです。2D画像やオーディオと違って、ダウンロード即実行可能、じゃなくて、間に一発いるんですね。
この解析部分、当然、タダのJavaScriptなんで、ふつーにシングルスレッドで走ります。 さぁ、もう嫌な予感がしてきましたね。
- これが複数ファイルだと、こうなります。ダウンロードは確かに時間のかかる処理かもしれないですが、ダウンロードは別スレッドですので、その間、画面を止めないのは、実はそれほど難しくない。 スピナーでもくるくる回しとけばいいんです。
ヤバイのはその後。 ここで、この1組の処理が終わるまで、画面の更新が一切行われなくなります。でもって、その次のファイルも同じように、長く止まっちゃうと。 もーヤバイです。スピナー君もこの最中は、回ってくれません。
- んで、こうなります。 秒間1フレームという地獄のできあがりです。
2m30
- じゃあどうしましょうってことで、魔法の呪文を唱えましょう。
みんな知ってるあの呪文です。
せーの!
- SetTimeOut!みんな大好き。最強です。今回もなんとかしてもらいましょう。
- ということで、解析が終わったところの、ロード後のコードのところで、SetTimeOutをはさみます。
- 元がコレですね。っていうかスライドのソースの字なんて見えませんね。ざっくりいきます。予想できると思いますけど、 コレを、
- こんな感じ。setTimeout の呼び出しを付けるだけ。これだけで、結構なんとかなります。
- この回収で、タイムライン的にはこんな感じになります。SetTimeOutのおかげで、画面更新のタイミングができます。
ぶっちゃけローポリで、アニメーションが長くないキャラだったら、これでなんとかなることも多いです。だがまだ足りないこともあると。
- これがデカイデータだとどうなるか。
自分のゲームのデータで3000頂点、5000フレームかな、ですと、解析時間だけで3秒。
画面ごと固まってるってのは、やっぱりキッツイですよね。まだなんとかしたい。なんとかできないだろうか。
- お前の力は、こんなもんじゃないだろと。まだいけます。なんとかしてもらいましょう。
- こっから先は、ソースをいじくるのが、ちょっと疲れます。必要ならば、やってみる感じです。
オープンソースって事を活かしましょう。フォークしても、ビルドしたやつをいじっても、どっちでもいいんじゃないですか。
- 例のMMDローダーを試しにいじってみることにしましょう。 元がコレですね。見えませんね。
まぁ続けますけど、見た感じ、二つの処理が繋がってるぞと。コレを、
- こうするわけですね。やったことは、さっきと同じです。
処理の区切りを意識して、見つけて、そこにSetTimeOutを仕込んでいく、それだけです。
- こうすることで、当然、トータルの読み込み時間は減りませんが、間に画面が更新できるタイミングが生まれます。
これを必要な負荷に応じて分割を増やすことで、止まったような画面を見なくて済む、かもしれません。頑張れば!
- ありがとうSetTimeout。今回も世界は救われた。君のことは忘れない!
- というわけで時間ないんですけど、自分のゲームのロード部分の図解です。
小刻みにいろいろなファイルが読まれていって、間あいだで画面の更新ができてます。ありがとうSetTimeOut! はい!
---------
最後に、自分が作ったゲームでの、データのロードの図解っぽいやつです。 (1分以上余ってた場合のみ全部言う)
最初に、ワイヤーフレームで表示する用の軽いモデルデータのダウンロードが走りまして、そのモデルのダウンロードと読み込みが終わると、いわゆる戦闘説明画面っぽいデモが入ります。そのデモ画面の最中、裏ではガリガリとダウンロードとダウンロード後の解析をやるわけですが、こんな感じでSetTimeOutを使って、それぞれが小刻みに読まれていく感じなんですね。んで、全部終わった所で本編突入です。これで、いわゆる「止まらないけど後ろではロードしてるんだぞ」という画面が可能になりました。何かの参考になれば幸いです。
- ちょっとお時間が余ってますので、 順番が前後しましたが、すりーじぇいえすの欠点といいますかなんといいますか、無理矢理な話しですけども。余談を話します。 unityのアセットストアが使えないので、データの用意に苦労することになるんですね。 3Dのデータって作れる人は2Dに比べたら一気に少なくなりますから、そこをカバーできるアセットストアは、ホント凄いと思います。リソースの自前は、おもったよりもキツイです。
まぁこれはあくまでUnityと比べたら、ということで。unity以外の環境からしたら、別に劣ってるということじゃないです。Unityがスゴすぎるだけ。 でも、 今日見せてだいたプレイカンバスは楽しそうだったので、 もし次、こういう機会があれば、プレイカンバスとの比較も用意してみたいなと思います。
- ということで、まとまらないまとめなんですけれども、 Unityでよくね、以上ですって、話が終わっちゃうので。ブラウザで公開したい!という特殊な事情がない限りは、別にthree.jsにこだわることって無いと思います。とにかく、3Dモデルデータが用意できるかどうか、まず最初の分かれ目はそこですね。
- --- 残り15s ------------
ということで、なんか今日話したことと全然関係ないまとめのようなんですけど、先ほどですね、オガワさんからWebGLでゲームはお金にはならんという泣ける結論がありましたけども、もしゲームを個人で作ってる人とかいらっしゃたら、three.jsは、ぜひやってみろと!面白いぞ!と、おすすめしたいと思います。
- ということで、おつきあいいただきまして、ありがとうございました。
すりーJSが気になった方はですね、ぜひとも画面に出てる、どーしょもないキーワードとかでググっていただいて、少しでも興味をもって頂けたら幸いです。 ということで、以上になります。 ありがとうございました。