ホーム < ゲームつくろー! < DirectX技術編 < 明るい光を表現するコツ


その14 明るい光を表現するコツ


 光源を見つめると非常にまぶしいものですが、いったい「眩しさ」って何なのでしょうか?それを体感するために、次の写真をご覧下さい。

 上の4枚の写真は私の家の蛍光灯を撮影したものです。左からシャッタースピードが1/800, 1/200, 1/60。一番右は白で塗りつぶしただけの絵です。さて、他の写真を手などで覆って隠しながら、左から順々に見ていって下さい。この中でどれが一番まぶしく感じるでしょうか?多分左から2番目、もしくは3番目ではありませんか?一番右側の絵は白い部分が一番多いのですが、これだけ見ると単なる白い絵であり、まぶしいとは感じないと思いませんか?

 右側の最大に白い絵と、真ん中2枚の絵、何が違うのかと言うと「蛍光管の周りのフレア」があるかないかです。フレア、いわゆる光源の周りにある光のもやと言いますか、背景と微妙に混ざった部分。人はこれを見ると「眩しいなぁ」と感じるのです。右の絵は白く完全に露光しているのですが、フレアが無いので眩しく感じられないのです。

 このように、明るい光を表現するには単に白くするのではなく「コツ」があります。この章ではDirect3Dを用いて「明るい」「眩しい」という表現を突き詰めてみます。



@ 「明るい」の基本は「露光オーバー」

 カメラのシャッタースピードを間違えて長くしてしまうと、フィルムが感光しすぎてしまい、眩し過ぎる写真になってしまいます。いわゆる露光オーバーです。写真全体が白くなってしまい、フレアだらけになるのが眩しいと感じる理由です。

 Direct3Dで明るさを表現するには「ビルボード+半透明のテクスチャ」を用いるのが常套手段になっています。この時、単に半透明合成をしたのではいくら重ねても明るくなりません。Direct3Dはオブジェクトをレンダリングする際に背景の画像の色とどう合成するかを決める事が出来ます。デフォルトでは手前のオブジェクトの色を100%使用するため背景の色は上書きされてしまいます。一方、露光を表現するには、背景の色とオブジェクトの色を「加算合成」します。まずはその設定を示します。

加算合成
m_cpD3DDev->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE);
m_cpD3DDev->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
m_cpD3DDev->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ONE );

一行目でアルファブレンドを許可し、2行目でソース(オブジェクト)のアルファ情報を用いてソースの合成比を決めます。アルファ値が0ならば抜けてしまうわけです。注目が3行目。D3DBLEND_ONEを設定してデスティネイト(背景)の色を100%加算してしまいます。色の値を式に書くと次のようになります。

Res = Sc * Sa + Dc * 1

Scはオブジェクトの色、それにSa(ソースのアルファ値)を掛け算します。。さらにDc(背景色)を100%足し算します。例えば、Sc、Sa、Dcをすべて1とした場合、ピクセルの色は2になってしまいますが、Direct3Dは1以上はすべて1に丸めます。よって、ある程度色が重なってしまうと、色が白く感光する状態になってしまいます。つまり写真の露光オーバーに近い状態を再現してくれます。これが、明るいの基本です。



A 加算合成だけではダメ

 加算合成によってカメラの露光効果が再現でき、「明るい」「眩しい」の基本がわかりました。ところで、下の絵をご覧下さい。

 これらはすべてDirect3D上で行った加算合成です。基本的に薄青い色を丸いアルファマスクでくり貫いています。見てお分かりの通り右下が飛びぬけて「明るい」「眩しい」と感じますよね。左上は真っ白な輪をアルファ値としました。100%でもこんなもんなんです。右上は少しフレアを入れたものです。「もやっと明るいか?」くらいですよね。左下はフレアを幾分大きくして、一部大きい箇所を設けています。また背景の青い絵にも白い輪を加筆しています。これだと大分に明るさを感じますね。そして、右下は左下のビルボードを同じ位置に2回重ねたものです。

 このことから、「凄い明るい!」と感じさせるには、フレアを大きめに描いて2回以上重ねれば良い事がわかります。加算合成による明かりの表現は、実はこの「重ね」が重要です。左上のように1枚だけではなんとも物足りない明かりで終わってしまいます。これは加算合成の式を見ればわかります。

Res = Sc * Sa + Dc * 1

 加算合成をする色Scが薄暗い場合、1回の重ねではさほどのプラスにはならないため露光が足りないのです。これをもう1回重ねると、

Res2 = Sc * Sa + Res * 1 = 2 * Sc * Sa + Dc * 1

見ての通り背景の色を1回、重ねるビルボードの色を2回使う結果になります。これが、より強い効果を生むのです。

 輪の色を工夫すれば、炎やレーザーなど、眩しい光源をいくらでも工夫できます。ちょっと楽しくなってきたので、適当にレーザー光線を作ってみました。


・・・雷ですな、これは(^^;。
でも「眩しさ」は十分に出ていますよね。右上がアルファ画像で右下がカラー情報です。3回重ねるとこうなりました。これは1枚絵ですが、工夫すればこういうレーザー砲をぶっ放す敵ボスみたいなのもきっと作れます!このレーザーでホーミングとか。そんなSTG、かっこ良いです(^-^)



B 光の演出は最後に

 光の合成で1つ注意があります。これは半透明合成すべてについて言える事ですが、Zバッファを用いてオブジェクトを並べる場合、半透明ビルボードを描いた後に後ろにオブジェクトを置いてはいけません。この場合、Zバッファによって後ろのオブジェクトは描かれなくなってしまいます。もっと酷いのは前のビルボードによって半分隠れていたりする場合で、透明なはずのビルボードのエッジがくっきりと見えてしまいます。多くの場合、光の演出は画面効果として使われますから、すべてのオブジェクトを描画した後に光を描くようにします。通常のオブジェクトを描画した後であれば、今度はZバッファが前後判断を正しく行ってくれるため、うまく光がなじみます。