2018-08-12
Google Developers Codelabsにあるチュートリアルの1つを触ってみた。
WebAssembly Physics and DOM objects (2018)
このチュートリアルでは砂時計を作成する。物理シミュレーションの部分をWebAssembly(wasm)で行うことで、とても高いパフォーマンスを実現している。
砂時計には全部で738個の砂粒がDOM要素として生成されているが、一粒一粒がちゃんと滑らかに動いている。
実際に動作するものは下記のURLから。
基本的にはチュートリアル通りに進めていけば間違いない。コードの雛形や砂時計のSVG画像はあらかじめ用意されているので、穴埋め形式で作成してく。
ちなみにこのチュートリアルは30分で終わると記載されていたが、全然そんなことはなかった。心を無にしてひたすらコピペすれば時間内で終わるかも。
以下ハイライト。
これが砂時計の初期状態。
砂粒が砂時計からはみ出ないように枠を定義する。(赤線部分)
物理エンジンにはC言語のライブラリであるChipmunk2Dを利用する。
当然、Chipmunk2Dはそのままだとブラウザ上で動かすことができないので、コンパイルツールチェーンの1つであるemscriptenでwasmに変換する必要がある。
$ git clone https://github.com/juj/emsdk.git
$ cd emsdk
$ ./emsdk install latest
$ ./emsdk activate latest
emscriptenのインストールと有効化。ダウンロードに15分くらいかかった。(ここで目安時間の半分消費)
$ source ~/emsdk/emsdk_env.sh
有効化できたら環境変数を設定する。パスは自分の環境に適宜合わせる。
emscriptenを使えるようにしたら、そのまま作業用のディレクトリ(work)まで移動。
チュートリアルに沿って、コードを入力したらmake
コマンドでwasmファイルを生成できる。
$ make
その結果、chipmunk.wasm
とchipmunk.js
という2つファイルが新たに生成される。
chipmunk.wasm
は物理計算を行うChipmunk2DをWasmモジュールにコンパイルしたもの。chipmunk.js
はemscriptenが生成したグルーコードで、ブラウザとwasmモジュールの橋渡しをする。
<script xlink:href="chipmunk.js"></script>
<script><![CDATA[
var wasm_loaded = false;
var cm_instance;
Module.onRuntimeInitialized = function() {
wasm_loaded = true;
cm_instance = Module._CM_Instance_new();
}
]]></script>
このチュートリアルでは便宜的にSVGファイルのなかに直接スクリプトを書いている。
まずchipmunk.js経由でwasmモジュールを読み込み、そのあとModule.onRuntimeInitialized
を使って処理を実行している。ちなみに Module.onRuntimeInitialized
に指定された関数は、wasmモジュールの読み込みが完了してはじめて呼び出される。
大量のDOMをこの程度の負荷で操作できるのは純粋にすごい。
今回のチュートリアルでChipmunk2Dというライブラリを使ったように、WebAssemblyを使えばC言語で書かれた多種多様なライブラリを活用できる。今後より一層、ブラウザ上で実現できることが増えていくのは間違いない。
個人的にはRustでWebAssemblyを使ってみたいので、先日オライリーから発売されたプログラミングRustを「読みたい本」リストに追加した。
2年後くらいにはWebAssemblyができて当たり前とかなってそうなので、これからちゃんとキャッチアップしていきたい。