恩恵を受けることをやってみましょう。今回は、ボリューム霧に挑戦してみます。世代に入って、より現実的なエフェクトになってきました。target:複数のレンダリングターゲットへ同時にレンダリングする)を使ってパス数を減らすことも行っています。(ボリューム霧:DirectX9)まぁ、いつものように適当にファイルが入っています。出力されるフレームワークのファイルは紹介を省かせていただきます。アプリケーションのソースあと、実行ファイル、表示用モデル及び、プロジェクトファイルが入っています。■ボリューム霧の考え方ボリューム霧ですが、考え方はシンプルです。そもそも、普段用いている霧は、現在自分がいる点から物体が描かれる点まで間の不純物による光の散乱をシミュレートしています。不純物粒子が特定の間にしか存在しない状態がボリューム霧です。ボリューム霧を再現するには、ボリュームの奥までの霧の濃度から、手前の濃度までの差を計算すればよいでしょう。ここで注意する点は、霧の中に不透明な物体があったときです。この時、不透明な物体の先にある不純物は見えませんから、不透明物体を霧の一番先の場所とみなして計算します。今回の描画の手順ですが、実は4パスです(しかもMRTを使ってさえも...)。1パス目で、MRTを使って、ボリューム霧の無い状態の色と深度をレンダリングします。今回、深度をR23Fフォーマットでレンダリングしましたが、ここは別にR8G8B8A8でもいいと思います。2パス目と3パス目で、フォグの厚みをレンダリングします。2パス目で表側の深度を加算で、3パス目で裏側の深度を減算でレンダリングします。最後に4パス目で、計算されたフォグの厚みから、ポスト処理でフォグの計算をしてボリュームレンダリングする物体を浮かび上がらせます。現在書き込んでいるバッファをテクスチャとしてレンダリングしています。この方法は禁じ手の1つです。描画の終了を待ちました。今度は精度が足りなくなるので一長一短です。いい忘れましたが、今回の方法は「表-裏」を計算するので、「閉じた」モデルで無いとだめです。モデルは凸のサブセットに分けて置いてください。■パス1:霧なしシーンのレンダリング今回は、パスごとに見ていきましょう。最初のレンダリングは、色と深度の描画です。この2つのシーンに関しては、同じ方向からの描画なので、MRTを使って1度に処理ができます。いう同時にレンダリングできる枚数を格納した変数があるので、この値を確認します。初期化の時に呼ばれます。必要な能力をチェックします。}では、シェーダを見てみましょう。深度を(テクスチャ座標として)いつもより多めに出力します。}今回は、MRTを使うので、ピクセルシェーダの出力がいつもの単純な色のベクトルではなく、構造体になります。2つの色の出力に、深度といつものレンダリング結果を出力します。}では、シェーダを呼び出すアプリケーション側のプログラムです。MRTの設定は簡単です。1つめの引数を変えて、2回呼び出すだけです。後は、いつもどおりです。シェーダの切り替えをして、変数をシェーダに設定してから描画します。m_pEffect->End();■パス2、3:霧ボリュームのレンダリングさて、霧のボリュームを計算します。2パス目と3パス目ではやっていることはほとんど変わりません。同じ頂点シェーダを使います。}2パス目と3パス目の違いは、表面と裏面を切り替えて、深度をレンダリングすることです。今回は、1つのテクスチャを使ってレンダリングします。最初に、表面を加算でレンダリングします。この時、分かりやすいようにすでに描かれた遮蔽物の深度からの差(を適当なスケーリングしたもの)を描画します。深度の奥にある部分は影響されないはずなので、その時には値を0にして、最終的な影響が出ないように修正します。3パス目では、裏面を減算で同様にレンダリングします。}表面と裏面の切り替えはエフェクトファイル内でできます。それぞれのパスで、D3DRS_を取っ払った変数で値を設定すると、レンダリングステートの設定ができます。}呼び出しプログラムですが、そんなに面白いものではありません。NULL)で、MRTを切るのを忘れないようにしましょう。後は、レンダリングターゲットをテクスチャに使うという危険な技を使うために、EndSceneで描画を区切る点が特別でしょうか。}■パス4:ボリューム霧の合成いよいよ最後のパスです。物体の裏に隠れる部分の処理を完全に省く)の考え方を踏襲して、2次元の全画面ポリゴンを1枚張るだけです。頂点シェーダはそれらを何もせずにピクセルシェーダに送ります。}ピクセルシェーダでは、フォグの体積をレンダリングした「fog_map」を合成パラメータとして、1パス目でレンダリングした結果とフォグの色を合成します。計算自体は単純な線形フォグです。好きな方は、お好きなように合成方法を変えてください。fog_map);アプリケーション側もそんなにたいしたことはありません。DirectX8と違って正しく処理できるようになっているので、オールドタイプの方は気をつけてください。テクセル中心をずらすための「0.5/テクスチャサイズ」です。(GeForce3のような2n以外のサイズのレンダリングターゲットを作れない場合もありますからね)。テクスチャやビューポートの計算が少し面倒くさくなっているので、ソースを見る方は注意してください。■最後にむむむ、浮動小数点数バッファはアルファ合成ができないので、意外と不便でした。負の値を保存できて値の範囲が大きくなると、このフォーマットが有利なのであるにこしたことは無いです。もどるimagire@gmail.com。