この記事は Web グラフィックス Advent Calendar 2021 の23日目の記事です。
はじめに
アドベントカレンダー7日目の記事でパスで囲まれた領域の描画をやってみましたが、アンチエイリアシングは難しいので挑戦しませんでした。
実際どんな計算するかを考えてみるほどに、ChromeとかFireFoxとかは本当によく描画できてるよなぁと思います。正確でしかも高速に。
CrhomeもFireFoxも内部的にはSkiaが使われているという噂をキャッチしてGitHubでソースコードを追ってみたりもしたのですが、アンチエイリアシングありの場合と無しの場合で明確にコードが分かれてるらしいな~くらいのことしか理解できず早々に諦めました。自分のスキルではどうして高速なのかが分かるほど理解するには相当時間が必要そうです。(数カ月かかるレベル)
しかし、高速さはともかく、どのくらい正確なのか(正確でない場合もあったりするのか)については極端なケースで実験してみれば何か分かるかもしれません。
実験内容
ということで、極端なケースとして、Canvas2Dで1ピクセルより細かい内容の描画をしてみます。
ケースは以下の5つを考えてみました。
- A. ピクセルに完全に納まる直線(一番左)
- B. ピクセルに完全に納まる中央位置のひし形塗りつぶし
- C. ピクセルの左に接したひし形塗りつぶし
- D. ピクセルの横境界をまたいだひし形塗りつぶし
- E. ピクセルの角を中心として四つのピクセルをまたいだひし形塗りつぶし(Chrome96は描画されず、FireFox94ではうっすら出ました)
See the Pen HTML/Canvas 1ピクセル内のアンチエイリアス処理の実験 by 柏崎ワロタロ (@warotarock) on CodePen.
実験結果
Chrome96の場合(左から準にA、B、C、D、E)
FireFox94の場合
うわっ地味っ… 結果を見ると、1ピクセルより小さい図形であるためか、だいたいは薄まった赤色が描画されています。また、図形としては本来同じものであっても、描画する位置によって濃さに違いが出ることがわかります。1ピクセルより細かい単位できちんと何かを計算しているんですね!
ブラウザ間の明確な違いとしては、ChromeはEのケースが全く描画されておらず、FireFox はうっすら描画されていることがあげられると思います。
これは描画を何回か繰り返してみると色が濃くなっていくのでよりはっきりと確認できます。
Eは4つのピクセルにまたがっているわけですから、正確さの観点でいうと、FireFoxのように4つのピクセルが描画されるほうがより正確であるといえるはずです。
微妙なケースとしては、Cのケースでは図形がピクセルの左境界に接していますが、Chromeではうっすら左のピクセルにも色が出ているのに対し、FireFoxでは一つのピクセルにのみ色が出ています。これはどちらがより正しいんでしょうか。ある意味どちらも正解のように思えます。
アンチエイリアシングの手法にも色々あって、正確な面積を計算する方法や、十数か所をサンプリングして決定するする方法があるらしいです。サンプリングによる方法であれば、サンプリングする位置が運悪く外れだった場合は今回のChromeのように全く色が出ないケースもありえます。今回の結果からすると、サンプリングのしかたに違いがあるのかもしれませんね。
ちなみに同日のMicrosoft EdgeはChromeと区別がつかない程度に同じ結果でした。Edgeは中身がChromeなので当然かもしれません。しかし、どのブラウザもSkiaを使って描画しているとすると、本来は全て同じ結果になるはずなので、そこは謎ですが未調査です。
まとめ
- ブラウザのアンチエイリアシングはすごいと思った
- ChromeとFireFoxで微妙に違う
- 同じSkiaを使っているとすると違いが出るのはなぜか?未調査のため謎が残った
未調査で終わってしまい申し訳ないのですが、そもそも重箱の隅をつつくような話ですので、どうかご容赦ください。
(毎回のように謝っている気が…)
アドベントカレンダーもあと二日ですね。それでは良いお年を。