題字の道具 斬 ZANで、作業用の canvas を使い回すように直した。速くなり、iPhone でも止まらなくなった。ところが、同じ設定・同じ種で描いた題字が、前と違う。刃の位置は同じ。飛び散った墨と、光の長さだけが変わっていた。
この研究を一言でいうと──何度も画素を読む canvas は、最初から CPU で描くと決めておく。
どれだけ違ったか
| 比べたもの | 結果 |
|---|---|
| 直す前の版を2回読み込む | 3枚とも一致 |
| 直す前 と 使い回した直後(既定の絵) | 35,935 画素が違う(墨の画素 120,644 の 29.8%) |
| 使い回し+最初から CPU で描く指定 | 2回読み込んで 3枚とも一致 |
直す前の版は、何度読み込んでも同じ絵になる。使い回した版だけが、違う絵を出した。
何が起きていたか
この道具は、刃を1本入れるたびに canvas の画素を読む。刃が字を抜けた場所を探すためだ。使い回した canvas は、何度も読まれる。ブラウザはそれを見て、途中から描き方を GPU から CPU に切り替える。切り替わると、字の縁の画素がわずかに変わる。縁が変われば、刃が字を抜ける場所の数が変わる。数が変われば、乱数を使う回数が変わり、そのあとの飛沫が全部ずれる。
直し方
- canvas を作った直後に「何度も読む」と伝える(willReadFrequently)。最初から CPU で描くので、途中で切り替わらない。
- 「同じ設定なら同じ絵」を確かめるときは、2回読み込んで画素で比べる。
- 刃の位置は乱数の最初の方で決まるので、同じに見える。ずれは、あとから使う乱数に出る。
あなたの道具は、同じ設定で、本当に同じ絵を出していますか。
— 他の研究を読む