RGSS2を知る(7)

Spriteのcolorプロパティの動作について。
マニュアルにはアルファ値が適用されつつブレンドされるという説明。具体的にさっぱりわからない。

b1 = Bitmap.new(100,100)
b2 = Bitmap.new(100,100)
b2.fill_rect(b2.rect, Color.new(255,0,0,128))
b3 = Bitmap.new(100,100)
b3.fill_rect(b2.rect, Color.new(128,0,128,255))

s1 = Sprite.new
s1.bitmap = b1
s1.color = Color.new(255,0,0,128)

s2 = Sprite.new
s2.bitmap = b2
s2.x = 200

s3 = Sprite.new
s3.bitmap = b2
s3.x = 400
s3.color = Color.new(255,0,0,128)

s4 = Sprite.new
s4.bitmap = b2
s4.y = 200
s4.color = Color.new(0,0,255,128)

s5 = Sprite.new
s5.bitmap = b3
s5.x = 200
s5.y = 200

loop do
  Graphics.update
end


左上は元画像が全部透明なもの。
その右は赤255、α128の画像。で、一番右はそれに赤255、α128をブレンド
左下は青255、α128をブレンド
その右は赤128青128α255の画像。


左上の画像の結果から言えることは、とりあえずcolorプロパティのブレンドというのは、αが0の画像に対しては何もおこらない、ということだ。
ここから、RGBをアルファブレンドして、元のα値を適用して描画しているか、もしくは描画してからcolorで指定したシルエット画像をアルファブレンドしている可能性が考えられる。
加算合成しているわけではないらしい。
上中央と右上が同じで、描画してからシルエット画像をアルファブレンドしていたらもう少し明るい色になるはずで、これが同じになるということは、元絵のαを無視してRGBに対してアルファブレンドし、結果に元絵のαを適用して描画しているのではなかろうか。
左下は青と赤のブレンドだが、下真ん中より暗く紫加減が同じという結果であり、上記の仮定と一致する。


これを計算式で表すと、
{Rd, Gd, Bd, Ad} * {1 - As, 1 - As, 1 - As, 1} + {Rs, Gs, Bs, As} * {As, As, As, 0}
という感じであり、こんなものはDirectX9のレンダーステートには無い。
この式はα付きブレンドとしては妥当なものだと思え、中間テクスチャをレンダーターゲットとして描画するならこうしないと結果がおかしくなるのだが、それがないDirectXがちょっと困ったちゃんなのだ。
なんしかこうなっているのならソフトウェアでブレンドしているか、ピクセルシェーダを使っていると考えられる。
その絞込みは描画性能で測る(通常描画とcolor指定時の動作速度差)ことで判定できるのではないかと思うので、後日実験してみようと思う。