Skip to main content

Module blur_box

Module blur_box 

Source
Expand description

ボックスブラーの高速実装(累積和による厳密な等価変換)。

仕様は spec/backdrop_blur.md

§なぜ必要か

backdrop-filter: blur() を持つ要素(sugi-lab.net のナビゲーションバー、 924×44)が 1 要素で 179〜478 tick かかっていた。 面積が 12 分の 1 の要素が 924×529 の要素より数倍重く、 これが paint の未特定分(約 53%)の正体だった。

素朴な 2 次元ボックスブラーは O(W×H×(2r+1)²)。 r は 1〜8 にクランプされるので最大 17×17 = 289 サンプル/ピクセル。 924×44 なら 1170 万回の加算を毎フレーム行っていた。

§方針

ボックスブラーは「クリップした窓の総和 ÷ 窓内の画素数」。 窓は矩形なので画素数は nx(x) × ny(y) に分解でき、 総和も行方向の窓和 H の縦方向の和に分解できる。 総和のまま持ち回れば除算は最後の 1 回だけになり、 素朴実装とビット単位で同一の出力になる(近似ではない)。

行ごとの累積和を使えば H は O(1) で引けるので全体は O(W×H) (半径に依存しない)。

§不変条件(B-1〜B-4)

  • B-1: 出力は素朴実装とビット単位で一致
  • B-2: 端は矩形内へクリップし、実際に含まれた画素数で割る
  • B-3: 除算は最後の 1 回だけ(途中で平均を取ると誤差が積もる)
  • B-4: 半径 0 以下・幅高さ 0 は何もしない

Functions§

box_blur_rgb
パック済み RGB(上位 8bit は無視し、出力では 0xFF を立てる)への ボックスブラー。
window_bounds
窓の範囲(両端含む)を 0..n へクリップして返す。