webworker内でwasmを使用しようとして失敗した(WebGL)
IPFactory Advent Calendar 2020 - Qiitaの8日目の記事
これの続き。
grekumu.hatenablog.jp
wasmの勉強で、こんな感じのやつGLSL Sandbox Gallery作ろうとしていて、wasmの処理をWebWorkerで行うつもりだったが、うまくできなかったって話。
WebWorker使おうと思った理由
www.sitepen.com
インストール
とりあえずworker-loader
をインストール。
npm install worker-loader --save-dev
config-overrides.js
に追加。
config.module.rules.push({ test: /\.worker\.js$/, use: { loader: 'worker-loader' } });
けどうまくいかない。
エラーや試したこと。
Uncaught SyntaxError: Unexpected token <
DevToolsで確認すると、WebWorkerがHTMLを返している。
あんまりWebWorker使ってこなかったから、構文が間違ってるか、loaderあたりだと思う。
グローバルオブジェクトの設定
webpackでHMRが有効だと、WebWorkerでwindow is not defined
ってなる話。
config-overrides.js
にグローバルオブジェクト設定してないせいかと思い、
config.output.globalObject = 'this';
と、設定した。
wasmのDynamic import
worker-loader
を使用し、WebWorker上からDynamic importするとエラーが出る。
これを見る限り、worker-loader
を使用しなければいいらしいので、とりあえず試してみた。
github.com
ReferenceError: Window is not defined.
Windowが大文字なのはlib.dom.d.ts
を参照しているから?
んで、よく考えるとこれDOM参照しようとしてる。
てか、そもそもwasm側でweb-sys
でcanvasを参照しており、結果的にWebWorker内でwindow
オブジェクトを参照していた。(早く気付け俺。)
解決策 OffScreenCanvas
を使う
今回の敗因はこれ。
描画はDOMに直接依存している。そのため、WebWorker上ではCanvasやWebGLの描画ができない。(これ理解してなかった。)
OffscreenCanvas
のレンダリングはDOMから完全に切り離されているため、WebWorker上で描画ができるようになる。
developers.google.com
MDN見た感じsafariとかFirefoxが未対応。
これ使えば対応してないブラウザは色々置き換えてくれるらしい?
GitHub - ai/offscreen-canvas: Polyfill for OffscreenCanvas to move Three.js/WebGL/2D canvas to Web Worker
おわり
ただ失敗したよって話。
customize-cra
やworker-plugin
とか色々試したけどそもそも無理だった。
まだOffScreenCanvas
を試してないから、まず試してみる。
アドカレ、他の人の記事と比べて内容ショボいとか言わないで。