VGBlendModeがよく分からない
Blendの概念がよく分からなかったので、丁寧に計算したメモ。
Alpha compositing - WikipediaとOpenVG仕様書を参考に
Porter-Duffによるブレンドを行う。
よく分からないので、実際に適当に計算してみる。
前提条件
不透過の背景(dst)に半透過で色を重ねる(src)。
色は青の背景に黄色で色を重ねることにする。
→srcα = 0.5, dstα = 1.0
→srcC = (1, 1, 0), dstC = (0, 0, 1)
最初に、色に対してαを乗算しておく。
OpenVGの仕様書ではpremultiplyとかかれている。
(premultiplyしない方法も書かれている)
srcC' = (0.5, 0.5, 0), dstC' = (0, 0, 1)
1.VG_BLEND_SRC_OVER:
outαは以下の式で求められる。
1 * srcα + (1-srcα) * dstα = 0.5 + 0.5 = 1
Alpha合成を行う。
outC = 1 * srcC' + (1-srcα) * dstC'
= (0.5, 0.5, 0) + (0, 0, 0.5)
= (0.5, 0.5, 0.5)
複数合成の順序を変えても成り立つようにするため、最後にoutαで割る。
outC / outα = (0.5, 0.5, 0.5)
灰色になりました。
2. VG_BLEND_SRC_IN:
outαは以下の式で求められる。
dstα * srcα + 0 * dstα = 0.5 + 0 = 0.5
Alpha合成を行う。
outC = dstα * srcC' + 0 * dstC'
= (0.5, 0.5, 0) + (0, 0, 0)
= (0.5, 0.5, 0)
合成の順番を変えても成り立つようにするため、最後にoutαで割る。
outC / outα = (1.0, 1.0, 0)
黄色になりました。重ねた色そのものです。
3.VG_BLEND_MULTIPLY
outαは以下の式で求められる。(Src overと一緒)
1 * srcα + (1-srcα) * dstα = 0.5 + 0.5 = 1
outCは以下の式で求められる。
outC = srcC' * (1 - dstα) + dstC' * (1 - srcα) + srcC'*dstC'
= (0, 0, 0) + (0, 0, 0.5) + ( 0, 0, 0 ) // 第3項は内積?
= (0, 0, 0.5)
暗い青になりました。乗算で暗くなる。
4.VG_BLEND_SCREEN
outαは以下の式で求められる。(Src overと一緒)
1 * srcα + (1-srcα) * dstα = 0.5 + 0.5 = 1
outCは以下の式で求められる。
outC = srcC' + dstC' - srcC'*dstC'
=(0.5, 0.5, 0) + (0, 0, 1) - (0, 0, 0)
=(0.5, 0.5, 1)
明るい青になりました。乗算の逆ですね。
5.VG_BLEND_DST_OVER
1の逆です。outαは以下の式で求められる。
(1-dstα) * srcα + 1 * dstα = 0 + 1 = 1
Alpha合成を行う。
outC = (1-dstα) * srcC' + 1 * dstC'
= (0, 0, 0) + (0, 0, 1)
= (0, 0, 1)
複数合成の順序を変えても成り立つようにするため、最後にoutαで割る。
outC / outα = (0, 0, 1)
やっぱり青です。
6.VG_BLEND_DARKEN/VG_BLEND_LIGHTEN
src overとdst overの暗い方/明るい方をとるとの事。
src over=(0.5, 0.5, 0.5)
dst over=(0, 0, 1)
ということで、
DARKEN=(0, 0, 0.5) 暗い青
LIGHTEN=(0.5, 0.5, 1)
7.VG_BLEND_ADDITIVE
単なる足し算です。1を超えたら1にします。
outα=min(srcα+dstα, 1)=min(1.5, 1)=1
outC=min(srcC'+dstC', 1)
=min((1.5, 1.5, 1), 1)
=(1, 1, 1)
最後にoutαで割りますが、結局白です。
画像で表示するとこんな感じ。
Imagination TechnologyのSDKを使用してます。