Top Banner
Unreal Engine 5 日で asm.js 化出来たと聞いて 2014/03/25 KLab ALM 余興 LT @muo_jp
35

UnrealEngineが5日間でasm.js化できたと聞いた俺たちは…

Nov 29, 2014

Download

Technology

Kei Nakazawa

http://slideshare.net/KeiNakazawa/web-pnaclasmjs-web の続きです。
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: UnrealEngineが5日間でasm.js化できたと聞いた俺たちは…

Unreal Engineが5日でasm.js化出来たと聞いて2014/03/25 KLab ALM 余興LT @muo_jp

Page 2: UnrealEngineが5日間でasm.js化できたと聞いた俺たちは…

 なかざわ けい   @muo_jp

プログラミング19年目 29歳(BASIC→C→PHP→Ruby→Python→C#2.0→C#3.0→C#4.0)

社会人 10年目(20歳~)、経営学修士(IT業界の経営戦略論)

KLab 4年目(Kラボラトリー所属 C#充)

PlaygroundというゲームエンジンのOSSメンテナ

Page 3: UnrealEngineが5日間でasm.js化できたと聞いた俺たちは…

どんな話? !

100,000行のC++コードを JavaScriptに変換する話

Page 4: UnrealEngineが5日間でasm.js化できたと聞いた俺たちは…

前日譚: C++/CLIで PSVita/PSMへ移植 しようとして失敗 (2013年ゴールデンウィーク)

Page 5: UnrealEngineが5日間でasm.js化できたと聞いた俺たちは…

前回までのあらすじ

Webの未来 ~ PNaClとasm.jsでカワルミライ - いま、モバイルWebの先端で起こっていること

http://www.slideshare.net/KeiNakazawa/web-pnaclasmjs-web

2013/11/22前後に調べてた諸々をまとめたもの

Page 6: UnrealEngineが5日間でasm.js化できたと聞いた俺たちは…

前回の結論

遠くない未来に、一定以上のコンテンツがWebへ回帰するはず

現状で見えている、C/C++で書かれたゲームエンジン移植の有力選択肢はPNaClとasm.js

この先は一度やってみたほうが見えてくるはず

Page 7: UnrealEngineが5日間でasm.js化できたと聞いた俺たちは…

Playgroundのアーキテクチャ

http://www.klab.com/jp/press/130926.html

Page 8: UnrealEngineが5日間でasm.js化できたと聞いた俺たちは…

asm.js化する部分

Page 9: UnrealEngineが5日間でasm.js化できたと聞いた俺たちは…

100,000行超のC++コード

Page 10: UnrealEngineが5日間でasm.js化できたと聞いた俺たちは…

まず10時間やってみよう

Page 11: UnrealEngineが5日間でasm.js化できたと聞いた俺たちは…

8時間ほどコードを削り倒す

Page 12: UnrealEngineが5日間でasm.js化できたと聞いた俺たちは…

当然一筋縄ではいかない

(`ェ´)ピャー

abort() at Error at stackTrace (/.../playground/Engine/porting/emscripten/p.js:1032:15) at abort (/.../playground/Engine/porting/emscripten/p.js:289649:25) at nullFunc_viiiiii (/.../playground/Engine/porting/emscripten/p.js:8235:1574) at Array.b978 [as 0] (/playground/Engine/porting/emscripten/p.js:287407:99) at Object._main (/.../playground/Engine/porting/emscripten/p.js:11640:43) at Object.callMain (/.../playground/Engine/porting/emscripten/p.js:289544:30) at doRun (/.../playground/Engine/porting/emscripten/p.js:289597:25) at run (/.../playground/Engine/porting/emscripten/p.js:289612:5) at Object.<anonymous> (/.../playground/Engine/porting/emscripten/p.js:289669:1) at Module._compile (module.js:456:26)

Page 13: UnrealEngineが5日間でasm.js化できたと聞いた俺たちは…

心折れました(3月上旬)

Page 14: UnrealEngineが5日間でasm.js化できたと聞いた俺たちは…

このへんをcodelunch.fmというpodcastで喋ってきました

Page 15: UnrealEngineが5日間でasm.js化できたと聞いた俺たちは…

12時間ほどおかわり

Page 16: UnrealEngineが5日間でasm.js化できたと聞いた俺たちは…

足りないライブラリのソースを拾ってきたりプラットフォーム依存部分を直したり

Page 17: UnrealEngineが5日間でasm.js化できたと聞いた俺たちは…

気合で読む 15945 $1 = 0; 15946 $2 = $argc; 15947 $3 = $argv; 15948 $width = 800; 15949 $height = 480; 15950 _emscripten_asm_const(((1168)|0)); 15951 $6 = (__Znwj(32)|0); 15952 $7 = $6; 15953 __THREW__ = 0; 15954 invoke_viiiiii(6,($7|0),((1264)|0),((1272)|0),((1280)|0),((1288)|0),((1296)|0)); 15955 $8 = __THREW__; __THREW__ = 0; 15956 $9 = $8&1; 15957 if (!($9)) { 15958 $pRequest = $7; 15959 $10 = (__ZN12CPFInterface11getInstanceEv()|0); 15960 $pfif = $10; 15961 $11 = $pRequest; 15962 __ZN15CAndroidRequest4initEv($11); 15963 $12 = $pRequest; 15964 __ZN15CAndroidRequest11setHomePathEPKc($12,(1312)); 15965 $vararg_ptr = ($vararg_buffer); 15966 HEAP32[$vararg_ptr>>2] = (1320); 15967 _emscripten_log(1,($vararg_buffer|0)); 15968 $13 = $pfif; 15969 $14 = $pRequest; 15970 $15 = $14; 15971 __ZN12CPFInterface18setPlatformRequestEP16IPlatformRequest($13,$15); 15972 (__ZN18KLBPlatformMetrics11getInstanceEv()|0);

Page 18: UnrealEngineが5日間でasm.js化できたと聞いた俺たちは…

asm.jsを読む

Page 19: UnrealEngineが5日間でasm.js化できたと聞いた俺たちは…

ifのelse側を冗長化して埋め込むケースもある。アセンブリ読んでるとよくあること。

Page 20: UnrealEngineが5日間でasm.js化できたと聞いた俺たちは…

多分MSILを日常的に読んでるC#勢からしたら朝食パンケーキ

みたいなもの

Page 21: UnrealEngineが5日間でasm.js化できたと聞いた俺たちは…

※sourcemapはちょい用途が違うので、やっぱアセンブリを読む

Page 22: UnrealEngineが5日間でasm.js化できたと聞いた俺たちは…

で、出来た結果は…

Page 23: UnrealEngineが5日間でasm.js化できたと聞いた俺たちは…

結果

Luaスクリプトの実行まで成功

glClearColorとか動く

テクスチャ描画はまだ

元版(iOS Simulator)

Chrome 33

Firefox 27

Page 24: UnrealEngineが5日間でasm.js化できたと聞いた俺たちは…

asm.js化できた部分

Page 25: UnrealEngineが5日間でasm.js化できたと聞いた俺たちは…

先は100時間+かかりそうだけど、 できそうな見立ては立った

Page 26: UnrealEngineが5日間でasm.js化できたと聞いた俺たちは…

以下asm.js読書感想文

Page 27: UnrealEngineが5日間でasm.js化できたと聞いた俺たちは…

ここがイケてるemscripten: ファイルシステムの扱い

非常に簡単にファイル群を取り込める

!

!

!

!

ちなみにWebブラウザ上で生成したデータをIndexedDB経由で永続化できる仕組みを提供してる

$ emcc -s ASSERTIONS=2 -s LEGACY_GL_EMULATION=1 --embed-file simple_item/@/install/ -O0 ./*.o -o p.html

16 Module['FS_createPath']('/', 'install', true, true); 17 Module['FS_createDataFile']('/install', 'itemimage.png.imag', [76, 73, 78, 75, 0, 0, 0, 17, 116, 101, 120, 116, 117, 114, 101, 66, 111, 97, 116 18 Module['FS_createDataFile']('/install', 'SimpleItem.lua', [102, 117, 110, 99, 116, 105, 111, 110, 32, 115, 101, 116, 117, 112, 40, 41, 13, 10, 19 Module['FS_createDataFile']('/install', 'start.lua', [102, 117, 110, 99, 116, 105, 111, 110, 32, 115, 101, 116, 117, 112, 40, 41, 13, 10, 101, 20 Module['FS_createDataFile']('/install', 'textureBoat.texb', [84, 69, 88, 66, 0, 1, 146, 43, 0, 18, 84, 116, 101, 120, 116, 117, 114, 101, 66, 1

Page 28: UnrealEngineが5日間でasm.js化できたと聞いた俺たちは…

ここがイケてるemscripten: EM_ASM();インラインアセンブリ的なインラインJavaScript

うわっと思うけど、無いより100倍マシ。良い選択

一応、この中で同スコープのポインタ触れる501 int main(int argc, char* argv[]) 502 { 503 int width = 800; 504 int height = 480; 505 EM_ASM( 506 Browser.createContext(Module.canvas, true, true, {}); 507 Browser.setCanvasSize(800, 480, true); 508 ); 509 510 CAndroidRequest * pRequest = new CAndroidRequest("model", "brand", "board", "version", "Asia/Tokyo"); 511 CPFInterface& pfif = CPFInterface::getInstance();

Page 29: UnrealEngineが5日間でasm.js化できたと聞いた俺たちは…

OpenGL ES 1.1用コールは 冷遇の姿勢

お、おう(PlaygroundはOpenGL ES 1.1+ターゲット)

4280 var glTexEnvi = (typeof(_glTexEnvi) != 'undefined') ? _glTexEnvi : function(){}; 4281 _glTexEnvi = _emscripten_glTexEnvi = function _glTexEnvi(target, pname, param) { 4282 GLImmediate.TexEnvJIT.hook_texEnvi(target, pname, param); 4283 // Don't call old func, since we are the implementor. 4284 //glTexEnvi(target, pname, param); 4285 };

emscripten/1.13.0/src/library_gl.js あたりを読む

Page 30: UnrealEngineが5日間でasm.js化できたと聞いた俺たちは…

地道デバッグ

一部を変更してem++でコンパイル、emccでJSファイルを吐き出してリロードあたりまでは10秒ぐらいでいける。かなりインタラクション速い

ただし: ChromeのJSコンソールで15万行越えのあたりにブレークポイントを止めようとすると30秒ぐらいかかる

Page 31: UnrealEngineが5日間でasm.js化できたと聞いた俺たちは…

リビルド最速を目指して

-O0コンパイル-O0リンク(8.8MiB・速い)

-O0コンパイル-O2リンク(2.7MiB・遅い)

-O2コンパイル-O2リンク(2.8MiB・遅い)

WonderSwan:emscripten keinakazawa$ ls -l p.* -rw-r--r-- 1 keinakazawa staff 101607 Mar 25 18:57 p.html -rw-r--r-- 1 keinakazawa staff 67 Mar 25 18:57 p.html.map -rw-r--r-- 1 keinakazawa staff 8967061 Mar 25 18:57 p.js -rw-r--r-- 1 keinakazawa staff 65 Mar 25 12:11 p.js.map

WonderSwan:emscripten keinakazawa$ ls -l p.* -rw-r--r-- 1 keinakazawa staff 101607 Mar 25 18:59 p.html -rw-r--r-- 1 keinakazawa staff 67 Mar 25 18:57 p.html.map -rw-r--r-- 1 keinakazawa staff 2831435 Mar 25 18:59 p.js -rw-r--r-- 1 keinakazawa staff 65 Mar 25 12:11 p.js.map

WonderSwan:emscripten keinakazawa$ ls -l p.* -rw-r--r-- 1 keinakazawa staff 101607 Mar 25 19:02 p.html -rw-r--r-- 1 keinakazawa staff 67 Mar 25 18:57 p.html.map -rw-r--r-- 1 keinakazawa staff 2941528 Mar 25 19:02 p.js -rw-r--r-- 1 keinakazawa staff 65 Mar 25 12:11 p.js.map

試行錯誤中はO0でビルド、実行成功まで 持っていくのが吉(ビルド時間が3倍ぐらい違う)

Page 32: UnrealEngineが5日間でasm.js化できたと聞いた俺たちは…

24時間付き合った印象

emscripten(asm.js)は、JSとC++で変わってくる部分をうまく吸収しつつ、時に美しく時に泥臭く(=最強)進行してるプロジェクト

Page 33: UnrealEngineが5日間でasm.js化できたと聞いた俺たちは…

残るJSのつらみ: メモリ空間共有できる マルチスレッド機構がないとpodcastで喋ってたら コメント頂いた

!

!

!

!

!

\( 'ω')/ウオオオオオアアアアアァァァーーッッッ!!https://bugzilla.mozilla.org/show_bug.cgi?id=933001

Page 34: UnrealEngineが5日間でasm.js化できたと聞いた俺たちは…

所感今のところは、携帯端末での動作よりもWindows/Mac上での動作に絞ったほうが良い結果になる(SDLと似た立ち位置)Luaのスクリプトを変更して3秒で動作確認できる(小規模なら)

開発中、どんどんリソースを書き換えていくのに良い

データサイズはやっぱり問題。けど、バックグラウンドロードをうまく実装すれば、少なくとも社内でのテスト用途には割といける?

もう少し進むと、従来WebView+…でやってたものの形が逆転する

Page 35: UnrealEngineが5日間でasm.js化できたと聞いた俺たちは…

今後に向けた手持ち課題Makefileをいい感じに整備

asm.js化するプロジェクトによって性質が異なるので、ちゃんと考える

差分ビルドをやりやすいように

emscripten固有部分をなるべく少ない箇所に閉じ込める

実行時にエラーとなりうる箇所をmake testなどで事前に掴めるように

これについては、非ブラウザ実行時(node.js実行時)にOpenGL系のコールを一切発行しないようにするなど、何かしらの手を入れる必要がある