« DCは何の略か。雑記の中身とは関係ない。 | トップへ戻る | お金が貯まらない理由。 »

2004年09月02日

32BitFloatでアルファブレンドはできるか

ちょっとDirectXの技術的なお話。

参考資料は二つ。

一つはt-pot半透明描画の話と、ITmediaのDX9のテクスチャフォーマットの話
前者はDirctX8でアルファブレンドをするための基本で、後者はテクスチャフォーマットによってブレンディングとかできたりできなかったりするよっていう資料。

さて、現在PC用のVGAとして最強と名高いGeForce6シリーズがあります。このVGAの地味な特徴の一つとして、D3DFMT_A32B32G32R32F、つまりARGB各要素が32BitFloatの精度を持つという激しいテクスチャへの対応が挙げられます。

ちなみに調査不足のため、いつの時点のVGAからこのフォーマットへの対応が始まったのかわかっていません。すいません。

VGAで32Bit精度というと、RADEONとGeForceFXの例の対決(RADEONは24Bitに抑えたためにH/W量が少なくコストパフォーマンスが高いという話)も有名ですが、ここでは置いておきましょう。24Bitなんていう中途半端な精度は眼中に無いので。

ところで、GPUコンピューティングという、グラフィックハードウェアを用いて色々な演算をしようという研究が近年にわかに注目を浴びています。描画処理を数値演算処理として扱うことで、VGAがベクトル計算機になるわけですね。細かい説明は省きましょう。

で、本題。アルファブレンドっていうのは、画像の重ねあわせの処理です。既に書かれている色と任意の割合で重ねあわせる加算描画、乗算描画、減算描画etc。これらはGPUコンピューティングにおいては加算、乗算、減算etcに相当する、基本的な演算です。その一方、GPUコンピューティングは基本的に数値計算なので、演算精度が高いと喜びます。もしくは演算精度が低いと見捨てられます。そしてGPUコンピューティングではテクスチャへの描画がレジスタへのデータの格納に相当します。

以上から、DirectXを使った(OpenGLを使うパターンも多いので念のため)GPUコンピューティングのためには、D3DFMT_A32B32G32R32Fでのアルファブレンドが必要不可欠になります。

で、やってみました。D3DFMT_A32B32G32R32F形式でD3DUSAGE_RENDERTARGETなテクスチャを作り、SetRenderStateで加算描画指定をして描画っ。
→結果:無理でした
あるフォーマットのテクスチャがアルファブレンドをできるかどうかはCaps Viewerでチェックすればわかるはずですが、私はその項目を知りません。ただ言える事は、D3DFMT_A8B8G8R8にしたら同じ処理で予想通りの色がついたということだけです。

さて、困りました。D3DFMT_A32B32G32R32Fでアルファブレンドができません。t-potの中の人のシェーダ本には、アルファブレンド関係はいまだに固定機能シェーダだという記述があるため、シェーダを使っても解決できそうにありません。

ちょっと待ってください。要するに複数のテクスチャの色を任意に混ぜ合わせて描画できればいいんですよね。ということは、複数枚のテクスチャを利用するピクセルシェーダを利用し、色情報を単純計算してあげればいいのではないでしょうか。

と、いうわけで実践。D3DFMT_A32B32G32R32Fでテクスチャを作成。SetTextureで二枚のテクスチャをセット。パスを指定してDrawPrimitiveUpで単純に描画。
HLSLのポイントは、
float4 PS_ADD ( VS_OUTPUT In ) : COLOR
{
float4 Color;

Color = tex2D( Samp1, In.Tex ) + tex2D( Samp2, In.Tex );

return Color;
}
という単純な加算という簡単プログラム。
→結果:見事に加算されました。

そんなわけで、D3DFMT_A32B32G32R32Fなテクスチャをアルファブレンドしたければ、シェーダを使えってことみたいです。簡単ですしね。

ちなみにこのアルファブレンド、一つのeffect->Begin~effect->End内で、
SetRenderTarget(texA);
SetTexture(num, texA);
SetTexture(num, texB);
DrawPrimitiveUp(...);
みたいに、描画対象のテクスチャをソースとしたブレンドをしてもちゃんと描画されるようなので、かなり使えそうですよ。


間違いが含まれてても責任は取りませんが、指摘してくれると血涙を流して喜ぶのでお願いします…。

D3DFMT_A32B32G32R32FがD3DFMT_A32R32G32B32Fになっていたので修正(笑えない)

投稿者 togabito : 2004年09月02日 17:45

Trackback Pings

このエントリーのトラックバックURL:
http://aaa.jspeed.jp/~togabito/cgi-bin/mt/mt-tbx.cgi/44

コメント

コメントしてください




保存しますか?