kumuのつぶやき

フロントエンド勉強中の学生のただつぶやき

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-syscanvasを参照しており、結果的にWebWorker内でwindowオブジェクトを参照していた。(早く気付け俺。)


解決策 OffScreenCanvasを使う

今回の敗因はこれ。
描画はDOMに直接依存している。そのため、WebWorker上ではCanvasWebGLの描画ができない。(これ理解してなかった。)

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-craworker-pluginとか色々試したけどそもそも無理だった。
まだOffScreenCanvasを試してないから、まず試してみる。
アドカレ、他の人の記事と比べて内容ショボいとか言わないで。