LoginSignup
6
7

More than 5 years have passed since last update.

アルファブレンドの高速化

Last updated at Posted at 2016-06-21

色深度が 8bit のアルファブレンドの計算式の定義を以下とする。
(dest * (255 - alpha) + src * alpha + 127) / 255

これを高速化するにはどうするか? 除算は遅いのでシフト演算などに変形するのが定石。

よく見かけるのが 255 ≒ 256 と見做してシフト演算に置き換えるだけの方法。
(dest * (255 - alpha) + src * alpha + 128) >> 8
255 → 256 では 1/255 の誤差がある。値域が 0~255 の計算においてこれは無視できない。
(実際に使ってみるとわかるが、最大値の 255 が得られないためブレンドを重ねるとだんだん暗くなる。)

では、16bit に桁を増やせば誤差が 1/65535 となって無視できるのではないだろうか?
まずは 255 での除算を 65535 での除算に変形してみる。
$\frac{x}{255} = \frac{x}{256 - 1} = \frac{(256 + 1)x}{(256 + 1)(256 - 1)} = \frac{257x}{65535}$

ということで 257 をかけてから 65535 で割る。
((dest * (255 - alpha) + src * alpha) * 257 + 32767) / 65535
そして 65535 ≒ 65536 と見做してシフト演算に置き換え。
((dest * (255 - alpha) + src * alpha) * 257 + ???) >> 16
??? の箇所は実際にプログラムで試してみて誤差が出なくなる値を見つけよう。

アセンブラで書く場合は x * 257(x << 8) + x といった細かな式変形も忘れずに。
さらに SIMD 命令を利用すると RGBA のブレンドを同時に行うことが可能。

6
7
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
7