マルチレンダーターゲット
DirectX SDKの「Post Process」的なものを作るために、
まずはマルチレンダーターゲットを試してみました。
1パスで同時に3つのテクスチャに描き込んでいます。
左上から通常のシーン、Normal Map(法線マップ)、Position Map(位置マップ)、
位置マップを加工した視点からの深度マップです。
サンプル
- post_process01.zip
- VC#2008EE用
- VertexShader2.0、PixelShader2.0以上
Multiple Render Targets(MRTs)のサポートを確認
- NumberSimultaneousRtsが3以上であれば、1パスで描画するためのテクニックを選択
- サポートしていなければ、3パスで描画
if( device.DeviceCaps.NumberSimultaneousRts >= 3 ) { use_pass = 1; use_MRTs = 3; technique = "render_scene"; } else { use_pass = 3; use_MRTs = 1; technique = "render_scene_3_pass"; }
scene.fx
//-------------------------------------------------------------------- //頂点シェーダ //-------------------------------------------------------------------- void VS_RenderScene( float4 pos : POSITION, float3 normal : NORMAL, float2 tex : TEXCOORD0, out float4 out_pos : POSITION, out float4 out_diffuse : COLOR, out float2 out_tex : TEXCOORD0, out float3 out_normal : TEXCOORD1, out float4 out_view_pos : TEXCOORD2 ) { /*...*/ } //-------------------------------------------------------------------- //ピクセルシェーダ //-------------------------------------------------------------------- //1パス用 void PS_RenderScene( float4 diffuse : COLOR, float2 tex : TEXCOORD0, float3 normal : TEXCOORD1, float3 pos : TEXCOORD2, out float4 out_color : COLOR0, out float4 out_normal : COLOR1, out float4 out_pos : COLOR2 ) { /*...*/ } //1パス目 void PS_RenderScene_Color( float4 diffuse : COLOR, float2 tex : TEXCOORD0, float3 normal : TEXCOORD1, float3 pos : TEXCOORD2, out float4 out_color : COLOR ) { /*...*/ } //2パス目 void PS_RenderScene_Normal( float4 diffuse : COLOR, float2 tex : TEXCOORD0, float3 normal : TEXCOORD1, float3 pos : TEXCOORD2, out float4 out_normal : COLOR ) { /*...*/ } //3パス目 void PS_RenderScene_Pos( float4 diffuse : COLOR, float2 tex : TEXCOORD0, float3 normal : TEXCOORD1, float3 pos : TEXCOORD2, out float4 out_pos : COLOR ) { /*...*/ } //-------------------------------------------------------------------- //テクニック //-------------------------------------------------------------------- technique render_scene { pass p0 { VertexShader = compile vs_2_0 VS_RenderScene(); PixelShader = compile ps_2_0 PS_RenderScene(); } } technique render_scene_3_pass { pass p0 { VertexShader = compile vs_2_0 VS_RenderScene(); PixelShader = compile ps_2_0 PS_RenderScene_Color(); } pass p1 { VertexShader = compile vs_2_0 VS_RenderScene(); PixelShader = compile ps_2_0 PS_RenderScene_Normal(); } pass p2 { VertexShader = compile vs_2_0 VS_RenderScene(); PixelShader = compile ps_2_0 PS_RenderScene_Pos(); } }
複数のレンダーターゲットにシーンを描画する
effect_scene.Technique = technique; //バックバッファを取得 using( RenderTarget backbuffer = new RenderTarget( device ) ) { int n = effect_scene.Begin( FX.None ); for( int pass = 0; pass < n; pass ++ ) { //1パスで可能であれば3つのレンダーターゲットをセット //3パスの場合は1つずつセット SetRenderTarget( pass ); device.Clear( ClearFlags.Target | ClearFlags.ZBuffer, Color.FromArgb( 0, 0, 0 ), 1.0f, 0 ); effect_scene.BeginPass( pass ); //シーンの描画 mesh.DrawSubset( 0 ); effect_scene.EndPass(); } effect_scene.End(); //レンダーターゲットをバックバッファに戻す backbuffer.Set( device ); }