XNAの方でもシャドウマッピングをやってみました。
シャドウマッピング★ 1.はじめに
XNAの方でもシャドウマッピングをやってみました。
★ 2.実装
シャドウマッピングについての説明はすでOpenGLのページの方(こちら)でやっているので,そちらを参考にしてください。
基本的にシェーダでの処理はOpenGLのときと同じです。同じじゃないのがcsファイルの方での処理です。 シャドウマッピングを作成して,シェーダの方に送ってやるわけですが,シャドウマッピングを作成する際に,レンダリングターゲットを作成して,レンダリングテクスチャをつくります。あと,このレンダリングターゲットを変更するときに解像度によっては深度バッファも作成しなくてはならないようです。深度バッファはDepthStencilBufferオブジェクトとして作成します。 00038: // レンダーターゲットなど 00039: RenderTarget2D renderTarget; 00040: DepthStencilBuffer depthBuffer; 00041: Viewport renderViewport; 00042: 00043: // シャドウマップのサイズ 00044: const int SHADOW_MAP_SIZE = 2048;シャドウマップのサイズは2048と結構大きめにしてみました。2048×2048のテクスチャを作成するので,そのままのビューポート使ってしまうとアスペクト比が異なるのでおかしくなりそうな気がしたので,テクスチャを作成する際にビューポートも変更するようにしてみました。renderViewportがシャドウマップ作成用のビューポートになります。 この用意した変数はLoadContent()メソッド内で初期設定を行っています。 00116: // レンダーターゲットの作成 00117: renderTarget = new RenderTarget2D( 00118: GraphicsDevice, 00119: SHADOW_MAP_SIZE, 00120: SHADOW_MAP_SIZE, 00121: 1, 00122: SurfaceFormat.Single); 00123: 00124: // デプスステンシルバッファの作成 00125: depthBuffer = new DepthStencilBuffer( 00126: GraphicsDevice, 00127: SHADOW_MAP_SIZE, 00128: SHADOW_MAP_SIZE, 00129: DepthFormat.Depth24Stencil8, 00130: MultiSampleType.None, 00131: 0); 00132: 00133: // シャドウマップ用のビューポートの設定 00134: renderViewport = GraphicsDevice.Viewport; 00135: renderViewport.Width = SHADOW_MAP_SIZE; 00136: renderViewport.Height = SHADOW_MAP_SIZE;あとは,Draw()メソッド内での処理ですが,まずシャドウマップを作成する際に,あとでまたデフォルトの状態で描画を行うので,デフォルト状態の深度ステンシルバッファやビューポートを一時退避させます。 デフォルト状態の変数を保存したら,シャドウマップ作成用に設定を変更し,シーンの描画を行います。 00185: 00186: /// 00187: /// Step.1 : シャドウマップの作成 00188: /// 00189: 00190: // 一時退避 00191: DepthStencilBuffer defaultDepth = GraphicsDevice.DepthStencilBuffer; 00192: Viewport defaultViewport = GraphicsDevice.Viewport; 00193: 00194: // 設定を変更 00195: GraphicsDevice.Viewport = renderViewport; 00196: GraphicsDevice.DepthStencilBuffer = depthBuffer; 00197: GraphicsDevice.SetRenderTarget(0, renderTarget); 00198: GraphicsDevice.Clear(Color.White); 00199:シャドウマップ作成用のシーンの描画が終わったら,変更した設定を元に戻します。 00228: // 設定を元に戻す 00229: GraphicsDevice.Viewport = defaultViewport; 00230: GraphicsDevice.DepthStencilBuffer = defaultDepth; 00231: GraphicsDevice.SetRenderTarget(0, null); 00232: GraphicsDevice.Clear(Color.CornflowerBlue);こんな具合でレンダリングテクスチャを作成します。 レンダリングテクスチャをシェーダに送る際は,RenderTarget2D.GetTexture()メソッドを使います。コードにするとしたのような感じです。 00255: effect.Parameters["ShadowMap"].SetValue(renderTarget.GetTexture());レンダリングテクスチャの作成の仕方さえわかれば,あとは行列送ったり,モデル描画する処理だけなので,そこまで難しいことはないんじゃないかと思います。 ★ Download
本ソースコードおよびプログラムを使用したことによる如何なる損害も製作者は責任を負いません。
本ソースコードおよびプログラムは自己責任でご使用ください。 プログラムの作成にはMicrosoft Visual Studio 2005 SP1 Professional, XNA Game Studio 2.0を用いています。 |