ブレンドファクター121
![]()
![]()
![]()
・続・表記について
便宜上SrcのRGBA値はrgba( Rs, Gs, Bs, As )、DestのRGBA値はrgba( Rd, Gd, Bd, Ad )と表記します。Srcの赤の要素はRsと書きます。
が、Direct3DでDestのα値は使えるのでしょうか?サーフェイスにαビットが使える訳でも無し。αテスト用のD3DRENDERSTATE_ALPHAREFの値を変えても無理でした。なので今回はAd(Destのα要素)は使えないものとします(1.0として計算)。でもDESTALPHAというのが実装されている以上は使えるはずだと思うんですが……。
・混合要素(Blend factor)
Direct3Dは、α合成の時SrcとDestに掛けるRGBA値を指定できます。このRGBA値を混合要素(Blend factor)と言います(D3DBLEND列挙型参照)。混合要素の種類は11種類、SrcとDestの組み合わせは11×11で121種類になります。121種類と言っても結果が同じ組み合わせもあるので、実際はもう少し減りますが。
今回は混合要素の組み合わせの特徴や用途、そしてD3DBLEND_〜ALPHA系ばかり使われてしまい何故かなかなか使われないD3DBLEND_〜COLOR系も注目してみましょう。……やっぱり混合要素よりブレンドファクターの方がしっくりくるなぁ。混合要素って直訳だし。DirectX5日本語ヘルプに混合要素と書いてあるんでそっちに合わせてます。ちなみにDirectX3日本語ヘルプではブレンディング係数だったりします。DirectX5日本語ヘルプってDirectX3版に比べてあんまり出来がよくない……。
・混合要素のRGBA値
Direct3Dの混合要素は11種類、まずはその混合要素のRGBA値を見てみましょう。
D3DBLEND_ZERO
rgba( 0, 0, 0, 0 )D3DBLEND_ONE
rgba( 1, 1, 1, 1 )D3DBLEND_SRCCOLOR
rgba( Rs, Gs, Bs, As )D3DBLEND_INVSRCCOLOR
rgba( 1-Rs, 1-Gs, 1-Bs, 1-As )D3DBLEND_SRCALPHA
rgba( As, As, As, As )D3DBLEND_INVSRCALPHA
rgba( 1-As, 1-As, 1-As, 1-As )D3DBLEND_DESTALPHA
rgba( Ad, Ad, Ad, Ad )D3DBLEND_INVDESTALPHA
rgba( 1-Ad, 1-Ad, 1-Ad, 1-Ad )D3DBLEND_DESTCOLOR
rgba( Rd, Gd, Bd, Ad )D3DBLEND_INVDESTCOLOR
rgba( 1-Rd, 1-Gd, 1-Bd, 1-Ad )D3DBLEND_SRCALPHASAT
rgba( f, f, f, 1) f = min( As, 1-Ad )
ここから、説明ではD3DBLEND_という部分を省略させていただきます。
Destのα要素の使い方がわからないので、Adを使う混合要素は抜き、ということで。SRCALPHASATなんか他とちょっと違ってそそられるんですけどねぇ……。
よく使われるのはZERO・ONE・SRCALPHA・INVSRCALPHAでしょうね。
この値をSrcとDestの色に掛けて足したのが結果になります。式で書くと、rgba( Rs, Gs, Bs, As ) * Srcの混合要素 + rgba( Rd, Gd, Bd, Ad ) * Destの混合要素
こんな感じです。計算し終わって描画される時には、画面に書くのはRGB要素だけでα要素は無視されます。α要素が使われるのは色との掛け算の時です。α要素同士の掛け算は意味を成しません。混合要素が〜ALPHA系でなければ掛け算でも使われません。α要素は必要無いです。
例) Src:SRCALPHA Dest:INVSRCALPHA Srcの色:rgba( 1.0, 1.0, 0.0, 0.8 ) Destの色:rgb( 0.0, 0.5, 1.0 )
rgba( Rs, Gs, Bs, As ) * rgba( As, As, As, As ) + rgba( Rd, Gd, Bd, Ad ) * rgba( 1-As, 1-As, 1-As, 1-As )
= rgba( 1.0, 1.0, 0.0, 0.8 ) * rgba( 0.8, 0.8, 0.8, 0.8 ) + rgba( 0.0, 0.5, 1.0, 1.0 ) * rgba( 0.2, 0.2, 0.2, 0.2 )
= rgba( 0.8, 0.8, 0.0, 0.64 ) + rgba( 0.0, 0.1, 0.2, 0.04 ) この時点でα要素の役目は終わっている
= rgba( 0.8, 0.9, 0.2, 0.68 ) α要素は無視して描画(描画色はrgb( 0.8, 0.9, 0.2 ))
・組み合わせ
SrcとDestそれぞれの混合要素の設定によって、いろいろな効果が使えます。
Src:D3DBLEND_SRCALPHA Dest:D3DBLEND_INVSRCALPHA
半透明ですね。Sa(Srcのα値)は不透明度に使います。混合要素を逆(SrcにINVSRCALPHA、DestにSRCALPHA)に指定した時は、Saは透明度として使います。わかりやすい方をどうぞ。不透明度として使う方がメジャーかな。
Dest
DirectX SDKに入ってる
湖のテクスチャ
Src
見ての通り赤い三角。
Sa(不透明度)は0.5
描画結果
Src:D3DBLEND_ONE Dest:D3DBLEND_ONE
こっちは加算合成。Src * 1.0 + Dest * 1,.0なので、Src + Destと同じ、つまりそのまま加算です。SrcをSRCALPHAにして使うと、明度がα値で指定できて便利です。
Dest
今回は三角以外の全ての
画像がJPEG形式なんで
画質がちょっと……
Src
色はrgb( 0.5, 0.0, 0.0 )
描画結果
Src:D3DBLEND_ZERO Dest:D3DBLEND_INVSRCALPHA
Destの明るさを暗くします。シャドウマップなど、影とかはこれで表現できます。他にもフェードアウト(画面の明るさを暗くしていく)にも使えますね。α値が小さいほど暗くなります。
これは一番最初の組み合わせ(SrcにSRCALPHA、DestにINVSRCALPHA)で代用できますけどね。Srcの色(RGB値)を黒にしたらいいだけなので。DestにINVSRCALPHAが設定されてるなら、RenderState変更の時間を考えると黒にして書いた方が断然良い。
Dest
Src
D3DBLEND_ZEROなので
色は無視される
描画結果
Src:D3DBLEND_ONE Dest:D3DBLEND_INVSRCALPHA
先程の組み合わせでは、SrcがZEROでRGB値の情報も使っていませんでした。そこで、SrcをONEにしてRGB値も設定することで、暗くするついでに加算合成も同時にしてしまおうという組み合わせです。
これで加算合成と半透明の中間みたいな効果が使えます。前回書いた、青空に爆発で紫になるという問題もある程度解決できます。指定するRGB値とα値の大きさが重要。
だんだん消えていくようにしたい時は、RGB値とα値両方をだんだん小さくします。加算合成ではRGB値を小さくして、半透明ではα値を小さくしてましたが、両方の特性を持つこの組み合わせでは両方小さくする必要があります。
ちょっと使い方が面倒で難しいかもしれないですね。でも半透明と加算合成が両極端なので、その2つの表現に限界を感じた時には役立つかもしれません。
加算合成
その中間?な使い方
半透明
Src:D3DBLEND_ZERO Dest:D3DBLEND_SRCCOLOR
Src * 0.0 + Dest * Srcで、 = Src * Destですね。乗算合成?
DestにSRCCOLORというのはなかなか便利です。Srcに指定する色によって、DestにRGB値それぞれ別々の掛け算を行う事ができるので(SRCALPHAだと掛ける値はRGB全てα値)。例えば画面のR値だけを半分にしたい時は、この混合要素を設定し、Srcの色をrgb( 0.5, 1.0, 1,0 )にして描画します。これを使って鮮やかな色の表現とかできそうですね。色付きセロハンや、色の付いたガラス玉などもこの混合要素を使います。透き通って向こうが見えるスライムとかこれでやったら綺麗かも。
ちなみに、SrcにDESTCOLOR、DestにZEROでもSrc * Dest + Dest * 0.0で結果は同じです。Src * Destには変わりありません。
Dest
Src
描画結果
よく英語の勉強に使う
セロハン?みたいな
Src:D3DBLEND_INVDESTCOLOR Dest:D3DBLEND_ZERO
この混合要素でSrcの色は白を指定します。……どんな効果になるでしょう?
この組み合わせだと、Destの色の反転になります。赤が水色に、青が黄色に。α合成で色の反転ができるとは!すごいぜINVDESTCOLOR!(←1人で感動) カラーキーと組み合わせて丸い形に反転とか、面白い演出効果ができるでしょう。
この混合要素で2度描画する(反転する)と元に戻ります。n * -1 * -1と同じ原理。
Dest
Src
描画結果
全画面描画した結果
Src:D3DBLEND_DESTCOLOR Dest:D3DBLEND_ONE
これもSrcの色は白を指定します。こうすると、描画する部分はDestの色が2倍の明るさになります。DestにSRCALPHAを指定すれば、α値を使って明るさの倍率を1.0〜2.0の間で指定できます(Srcの明るさを調整しても同じ事が可能)。あと、Srcの色によって結果を調節できます。赤(rgb( 1.0, 0.0, 0.0 ))を指定すれば、赤の成分だけ2倍にできます。rgb( 0.5, 0.0, 0.0 )なら赤の成分だけ1.5倍。
一番使えるのはライトでしょうね。明るくするようなライトマップとかでも可。ビット数による精度が心配ですが。白へのフェードアウト(白の半透明に比べるとまぶしい感じのフェードアウト)とかにも使えると思います。……こっちは使うことは少なそうですね。黒をいくら2倍にしても黒だから、黒や青など0.0を含む色が画面に残ってしまう。全画面加算合成とかと一緒に使いましょう。
Dest
Src
描画結果
全画面描画した結果
赤の三角を描画した結果
赤の要素だけが2倍に
αテストやテクスチャのαビット、マルチテクスチャなどを一緒に使えば表現の幅がかなり広がります。αテストについてはこの次書く予定の「カラーキーを超える者」で説明します。
SrcのRGB値、α値、Srcのテクスチャ、DestのRGB値、混合要素……いろいろな値が関わってくるので、あれこれ考えてみて新しい表現方法を模索してみましょう。FriedChicken氏のページにα合成を使った水の表現があります。マルチテクスチャを使うと意外な混合要素の組み合わせを使う事になるかもしれません。何か有効な混合要素の組み合わせが思い付いた方は、ぜひ掲示板に書いていってください。
半透明と加算合成以外のα合成ももっと使っていきましょう。使おうとしても使う機会が無いでしょうけど……。
・おまけ 実装について
マイナーな機能って実装がまちまちな場合がありますけど、混合要素についても同じ事が言えるでしょう。〜COLOR系の混合要素はあまり使われないので、他とは違う実装もあるかもしれません。
うちのGA-RUSH6(VoodooRush)の話。SRCCOLORとINVSRCCOLORの混合要素は、Srcに使おうとDestに使おうと混合要素と掛ける値がDestの色になります。でもSrcにSRCCOLORを指定する事もほとんど無いだろうから、あまり問題ありません。と言うか自分はこっちの実装の方が可能性がありそうで好きです。
Reference Rasterizer(模範実装?)と違う限りは非互換な実装なんですが。そういえば書き忘れてましたが、DirectX6になってHELでもα合成が使えるようになりました。しかも全ての混合要素が使えます。もうDirectX6様々ですなぁ。速度の面でもそれほど遅くありません。α合成を使った時と使わない時の違いを実感した事もありませんし。それ以前にHELのフィルレート(ポリゴンを塗りつぶす速度)がHALと比較にならないほど遅いのですが。
![]()
![]()
![]()
written by Y.Ohde e-mail : oode@alles.or.jp