Microsoft Visual Express 2013 for Desktop C++
 Direct3D 11.0( SM 5.0 )
 DirectXTex texture processing library
 XMLLite

■Direct3D11 Colored Stochastic Shadow Maps Prev Top Next
関連ページ:Direct3D11 自作ライブラリ


今回はColored Stochastic Shadow Mapsというものをやります。日本語では確率論的なカラーシャドウマップですかね。
前回同様、日本語解説しているサイトがなかったので、英語論文を適当に解釈して実装しました。
論文はここです。

できはなよくないのですが、一応完成したのでアップしておきます。

概要について簡単に説明すると、ぶっちゃけ色がついた投影シャドウマップです。
これは、普通に実装しようとすれば、RGB成分を持つカラーマップ( 透明度マップ )と深度マップを使用すると思います。
今回のネタはこのカラーマップと深度マップを一個のマップにまとめてメモリ使用量を低減しようというものです。
ではどうやってまとめるかというと、ノイズマップを使用して遮蔽率を確立的に計算していくわけですが、
メッシュのアルファチャンネルを変更しつつ、サンプルを動かしたほうがわかりやすいかもですので、説明はここまでとします。すいません。

アルゴリズムは以下の流れになります。
1.不透明メッシュの深度値を取得。
2.1をRGBカラー・深度マップにコピー。
3.ブレンドステートで深度テストを行う設定にして、半透明メッシュのカラーと深度値を取得。このときノイズマップを使用して深度値の更新を制御する。
4.3のカラー・深度マップをPCFを使用してぼかして、カラー( 場合によっては影 )をメッシュに適用する。

といった感じになります。
ブレンドステートで深度テストを行う方法については、UGraphicsPipeline.cppを参照してください。


@Direct3D 自作の共通ライブラリ一式をここを参照して作成してください。

Aシェーダー系で使用するソースです。
ColoredStochasticShadowMaps_Pass0.hlsl 不透明メッシュの深度マップを生成するシェーダーソース
ColoredStochasticShadowMaps_Pass1.hlsl 半透明メッシュのカラーおよび深度マップを生成するシェーダーソース
ColoredStochasticShadowMaps_Pass2.hlsl シャドウを適用するためのシェーダーソース
ColoredStochasticShadowMaps.h ColoredStochasticShadowMapsクラスのヘッダーファイル
ColoredStochasticShadowMaps.cpp ColoredStochasticShadowMapsクラスのソースファイル

B個別に使用するソースです。
WallMesh.h 壁メッシュクラスのヘッダーファイル
WallMesh.cpp 壁メッシュクラスのソースファイル
PlaneMesh.h 地面メッシュクラスのヘッダーファイル
PlaneMesh.cpp 地面メッシュクラスのソースファイル
main.cpp main関数のソースファイル


---ColoredStochasticShadowMaps_Pass0.hlsl---  ↑

// ************************************************************
// Colored Stochastic Shadow Maps    ポリゴンの深度値
// ************************************************************

// 定数バッファ
cbuffer CBuffer : register( b0 )
{
   column_major float4x4 g_matLightWorldViewProj  : packoffset( c0 );    // ライトビューのワールドビュー正射影行列
};

// 頂点シェーダーの入力パラメータ
struct VS_IN
{
   float3 pos    : POSITION;    // 頂点座標
   float3 normal : NORMAL;      // 法線ベクトル
   float2 texel  : TEXCOORD;    // テクセル
};

// 頂点シェーダーの出力パラメータ
struct VS_OUT_PS_IN
{
   float4 pos      : SV_POSITION;
};

// 頂点シェーダー
VS_OUT_PS_IN ColoredStochasticShadowMaps_Pass0_VS_Main( VS_IN In )
{
   VS_OUT_PS_IN Out;

   Out.pos = mul( float4( In.pos, 1.0f ), g_matLightWorldViewProj );
   return Out;
}

---ColoredStochasticShadowMaps_Pass1.hlsl---  ↑


// ************************************************************
// Colored Stochastic Shadow Maps  カラーマップの作成
// ************************************************************

// 定数バッファ
cbuffer CBuffer : register( b0 )
{
   column_major float4x4 g_matLightWorldViewProj  : packoffset( c0 );    // ライトビューのワールドビュー射影行列
};

// テクスチャー
Texture2D g_GlassMap : register( t0 );
Texture2D  g_NoiseMap : register( t1 );

// サンプラーステート
SamplerState g_GlassSampler : register( s0 );
SamplerState g_NoiseSampler : register( s1 );

// 頂点シェーダーの入力パラメータ
struct VS_IN
{
   float3 pos    : POSITION;    // 頂点座標
   float3 normal : NORMAL;      // 法線ベクトル
   float2 texel  : TEXCOORD;    // テクセル
};

// 頂点シェーダーの出力パラメータ
struct VS_OUT_PS_IN
{
   float4 pos      : SV_POSITION;
   float2 texel    : TEXCOORD0;
   float4 posWVP   : TEXCOORD1;
};

// 頂点シェーダー
VS_OUT_PS_IN ColoredStochasticShadowMaps_Pass1_VS_Main( VS_IN In )
{
   VS_OUT_PS_IN Out;

   Out.pos = mul( float4( In.pos, 1.0f ), g_matLightWorldViewProj );
   Out.texel = In.texel;
   Out.posWVP = Out.pos;

   return Out;
}

// ピクセルシェーダ
float4 ColoredStochasticShadowMaps_Pass1_PS_Main( VS_OUT_PS_IN In ) : SV_TARGET
{
   float4 Out;

   float4 col = g_GlassMap.Sample( g_GlassSampler, In.texel );

   float2 texel = float2( In.posWVP.x / In.posWVP.w * 0.5f + 0.5f, In.posWVP.y / In.posWVP.w * -0.5f + 0.5f );

   float noise = g_NoiseMap.Sample( g_NoiseSampler, texel ).r;

   float3 rgb;

   float z = In.posWVP.z / In.posWVP.w;

   for( uint i=0; i<3; i++ )
   {
      // 色はカラーマップを適用するとき、積算合成するため反転する。
      // アルファチャンネルが0のときはrgb[i]が常に1になるため、深度バッファへの書き込みが行われない。つまり透明になる。
      // アルファチャンネルが1のときはnoiseが常に0になるため、深度マップの最前面で書き込まれる。
      float p = ( 1.0f - col[i] ) * col.a;

      // p が大きいほど、手前側の深度値がで書込まれやすくなる
      if( noise * ( 1.0f - col.a ) <= p )
         rgb[i] = z;

      // 書込みしない
      else
         rgb[i] = 1;
   }

   return float4( rgb, 0 );
}

論文上にあるカラー・深度マップの画像みるとどうも違うような気がするのですが、とりあえず良しとしておきます。

---ColoredStochasticShadowMaps_Pass2.hlsl---  ↑


// ************************************************************
// Colored Stochastic Shadow Maps  カラーマップをレンダリング
// ************************************************************

// 定数バッファ
cbuffer CBuffer : register( b0 )
{
   column_major float4x4 g_matLightWorldViewProj  : packoffset( c0 );   // ライトビューのワールドビュー射影行列
   column_major float4x4 g_matCameraWorldViewProj  : packoffset( c4 );   // カメラビューのワールドビュー射影行列
};

// テクスチャー
Texture2D g_DecalMap : register( t0 );

// カラー深度マップ
Texture2D g_ColorAndDepthMap : register( t1 );

// サンプラーステート
SamplerState g_SamplerDecalMap : register( s0 );
// サンプラーステート
SamplerState g_SamplerColorAndDepthMap : register( s1 );

// 頂点シェーダーの入力パラメータ
struct VS_IN
{
   float3 pos    : POSITION;    // 頂点座標
   float3 normal : NORMAL;      // 法線ベクトル
   float2 texel  : TEXCOORD;    // テクセル
};

// 頂点シェーダーの出力パラメータ
struct VS_OUT_PS_IN
{
   float4 pos      : SV_POSITION;
   float3 normal   : NORMAL;
   float2 texel    : TEXCOORD0;
   float4 posLWVP  : TEXCOORD1;
};

// 頂点シェーダー
VS_OUT_PS_IN ColoredStochasticShadowMaps_Pass2_VS_Main( VS_IN In )
{
   VS_OUT_PS_IN Out;

   Out.pos = mul( float4( In.pos, 1.0f ), g_matCameraWorldViewProj );
   Out.normal = In.normal;
   Out.texel = In.texel;
   Out.posLWVP = mul( float4( In.pos, 1.0f ), g_matLightWorldViewProj );

   return Out;
}

// ピクセルシェーダ
float4 ColoredStochasticShadowMaps_Pass2_PS_Main( VS_OUT_PS_IN In ) : SV_TARGET
{
   float4 Out;
   float4 col = g_DecalMap.Sample( g_SamplerDecalMap, In.texel );

   float2 texel = float2( In.posLWVP.x / In.posLWVP.w * 0.5f + 0.5f, In.posLWVP.y / In.posLWVP.w * -0.5f + 0.5f );

   if( texel.x >= 0.0f && texel.x <= 1.0f && texel.y >= 0.0f && texel.y <= 1.0f )
   {
      // ライトビュー上でのピクセルの深度値
      float depth = In.posLWVP.z / In.posLWVP.w - 0.0085f;

      float4 depthmap;

      // RGBループ
      for( int i=0; i<3; i++ )
      {
         float PercentLit = 0;
         float cnt = 0;

         // PCF( R16G16B16A16_FLOATフォーマットの場合、SampleCmpLevelZero()は使えないっぽい )
         for( int x=-4; x<5; x+=2 )
         {
            for( int y=-4; y<5; y+=2 )
            {
               depthmap = g_ColorAndDepthMap.Sample( g_SamplerColorAndDepthMap, texel, int2( x, y ) );
               // 深度マップの深度値のほうが奥にあるときは影を落とさない
               if( depthmap[i] > depth )  PercentLit++;

               cnt++;
            }
         }

         // 平均値を計算する
         col[i] *= ( PercentLit / cnt );
      }
   }
   
   return col.bgra;
}

R16G16B16A16_FLOATフォーマットの場合、SampleCmpLevelZero()が使えないっぽいので普通に実装しました。

---ColoredStochasticShadowMaps.h---  ↑

#ifndef COLORED_STOCHASTIC_SHADOW_MAPS_H
#define COLORED_STOCHASTIC_SHADOW_MAPS_H

#include "../Common/UCommon.h"
#include "../Common/UException.h"
#include "../Common/UGraphicsPipeline.h"
#include "../Common/UDirect3D11.h"
#include "../Common/USRViewRenderer.h"

// XNAMath
#include "../Common/XNAMath/xnamath.h"

class ColoredStochasticShadowMaps
{
private:
   // Direct3D用定数バッファ設定用構造体

   // 不透明メッシュの深度値を出力
   typedef struct _CBUFFER_PASS0
   {
      XMMATRIX matLightWorldViewProj;
   }CBUFFER_PASS0;

   // 半透明メッシュのカラーマップおよび深度マップ作成
   typedef struct _CBUFFER_PASS1
   {
      XMMATRIX matLightWorldViewProj;
   }CBUFFER_PASS1;

   // カメラビューからレンダリング
   typedef struct _CBUFFER_PASS2
   {
      XMMATRIX matLightWorldViewProj;
      XMMATRIX matCameraWorldViewProj;
   }CBUFFER_PASS2;

   // 不透明メッシュの深度マップ
   ID3D11DepthStencilView* m_pDSViewOfOpacityDepthMap;
   ID3D11ShaderResourceView* m_pSRViewOfOpacityDepthMap;

   // 半透明カラーマップおよび深度マップ
   ID3D11RenderTargetView* m_pRTViewOfTranslucentColorAndDepthMap;
   ID3D11ShaderResourceView* m_pSRViewOfTranslucentColorAndDepthMap;
   // サンプラーステート
   ID3D11SamplerState* m_pSamplerStateOfColorAndDepthMap;

   // ノイズマップ
   ID3D11ShaderResourceView* m_pSRViewOfTNoiseMap;
   // サンプラーステート
   ID3D11SamplerState* m_pSamplerStateOfNoiseMap;

   // レンダーターゲットと深度ステンシルとビューポートのバックアップ
   ID3D11RenderTargetView* m_pOldRTView[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT];
   ID3D11DepthStencilView* m_pOldDSView;
   D3D11_VIEWPORT m_pOldViewport[D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE];
   UINT m_ViewportCount;

   // シェーダー用定数バッファ
   ID3D11Buffer* m_pConstantBuffers[3];

   UGraphicsPipeline* m_pGraphicsPipeline[3];

   // 深度マップの色をカラーマップにコピーするときにクラス。フォーマットが異なるので、CopyResource()とか使えない。
   USRViewRenderer* m_pSRViewRenderer;

   DWORD m_Width, m_Height;

   int m_Pass;

   XMMATRIX m_MatLightView;
   XMMATRIX m_MatLightProj;
   XMMATRIX m_MatCameraView;
   XMMATRIX m_MatCameraProj;
   XMFLOAT4 m_VecLightPos;

public:
   ColoredStochasticShadowMaps();
   virtual ~ColoredStochasticShadowMaps();
   void Invalidate();
   void Create( ID3D11Device* pD3DDevice, DWORD Width, DWORD Height );
   void BeginPass( ID3D11DeviceContext* pD3DDeviceContext, UINT Pass,
                   XMFLOAT4* pVecLightPos, XMMATRIX* pMatLightProj, XMMATRIX* pMatCameraView, XMMATRIX* pMatCameraProj );
   void SetConstantBuffers( ID3D11DeviceContext* pD3DDeviceContext, XMMATRIX* pMatWorld );
   void EndPass( ID3D11DeviceContext* pD3DDeviceContext );
   inline UINT GetMaxPass(){ return 2; };
   inline const ID3D11ShaderResourceView* GetOpacityDepthMap(){ return m_pSRViewOfOpacityDepthMap; };
   inline const ID3D11ShaderResourceView* GetTranslucentColorMap(){ return m_pSRViewOfTranslucentColorAndDepthMap; };
   inline const ID3D11ShaderResourceView* GetNoiseMap(){ return m_pSRViewOfTNoiseMap; };
};
#endif

不透明メッシュをレンダリングして生成した深度マップの深度値をカラー・深度マップにコピーするために、USRViewRendererクラスを使用します。
フォーマットが異なると、ID3D11DeviceContext::CopyResource()とか使えないみたいなので。

---ColoredStochasticShadowMaps.cpp---  ↑


#include "../../Header/Shader/ColoredStochasticShadowMaps.h"
#include "../../HLSL/ColoredStochasticShadowMaps_Pass0_VS_Main.h"
#include "../../HLSL/ColoredStochasticShadowMaps_Pass1_VS_Main.h"
#include "../../HLSL/ColoredStochasticShadowMaps_Pass1_PS_Main.h"
#include "../../HLSL/ColoredStochasticShadowMaps_Pass2_VS_Main.h"
#include "../../HLSL/ColoredStochasticShadowMaps_Pass2_PS_Main.h"

ColoredStochasticShadowMaps::ColoredStochasticShadowMaps()
{
   m_pDSViewOfOpacityDepthMap = nullptr;
   m_pSRViewOfOpacityDepthMap = nullptr;
   m_pRTViewOfTranslucentColorAndDepthMap = nullptr;
   m_pSRViewOfTranslucentColorAndDepthMap = nullptr;
   m_pSRViewOfTNoiseMap = nullptr;
   for( int i=0; i<_countof( m_pGraphicsPipeline ); i++ )
   {
      m_pGraphicsPipeline[i] = nullptr;
      m_pConstantBuffers[i] = nullptr;
   }
   m_pSRViewRenderer = nullptr;
   m_pSamplerStateOfNoiseMap = nullptr;
   m_pSamplerStateOfColorAndDepthMap = nullptr;

   m_Pass = -1;
}

ColoredStochasticShadowMaps::~ColoredStochasticShadowMaps()
{
   SAFE_RELEASE( m_pSamplerStateOfColorAndDepthMap );
   SAFE_RELEASE( m_pSamplerStateOfNoiseMap );
   SAFE_DELETE( m_pSRViewRenderer );
   for( int i=0; i<_countof( m_pGraphicsPipeline ); i++ )
   {
      SAFE_DELETE( m_pGraphicsPipeline[i] );
      SAFE_RELEASE( m_pConstantBuffers[i] );
   }
   SAFE_RELEASE( m_pSRViewOfTNoiseMap );
   SAFE_RELEASE( m_pSRViewOfTranslucentColorAndDepthMap );
   SAFE_RELEASE( m_pRTViewOfTranslucentColorAndDepthMap );
   SAFE_RELEASE( m_pSRViewOfOpacityDepthMap );
   SAFE_RELEASE( m_pDSViewOfOpacityDepthMap );
}

void ColoredStochasticShadowMaps::Create( ID3D11Device* pD3DDevice, DWORD Width, DWORD Height )
{
   m_Width = Width;
   m_Height = Height;

   m_Pass = -1;

   // *******************************************************************************************************
   // 不透明メッシュの深度マップ作成
   // *******************************************************************************************************

   m_pGraphicsPipeline[0] = NEW UGraphicsPipeline();

   // ラスタライザーステートを作成する
   m_pGraphicsPipeline[0]->CreateRasterizerState( pD3DDevice, D3D11_CULL_MODE::D3D11_CULL_BACK );

   // 深度ステンシルステートを作成する
   m_pGraphicsPipeline[0]->CreateDepthStencilState( pD3DDevice, TRUE, D3D11_DEPTH_WRITE_MASK::D3D11_DEPTH_WRITE_MASK_ALL );

   // ブレンドステートを作成する
   UGraphicsPipeline::UEBLEND_STATE BlendStateType[1] = { UGraphicsPipeline::UEBLEND_STATE::NONE };
   m_pGraphicsPipeline[0]->CreateBlendState( pD3DDevice, BlendStateType, 1 );

   D3D11_INPUT_ELEMENT_DESC layout[] = {
         { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0,  0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
         { "NORMAL",   0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
         { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT,    0, 24, D3D11_INPUT_PER_VERTEX_DATA, 0 },
   };

   // シェーダーを作成する
#if defined(DEBUG) || defined(_DEBUG)
   m_pGraphicsPipeline[0]->CreateVertexShaderFromFile( pD3DDevice, _T("../HLSL/ColoredStochasticShadowMaps_Pass0.hlsl"), "ColoredStochasticShadowMaps_Pass0_VS_Main", layout, _countof( layout ) );
#else
   m_pGraphicsPipeline[0]->CreateVertexShaderFromMemory( pD3DDevice, (LPBYTE)g_ColoredStochasticShadowMaps_Pass0_VS_Main, sizeof( g_ColoredStochasticShadowMaps_Pass0_VS_Main ), layout, _countof( layout ) );
#endif
 
   // 深度ステンシルバッファを作成する
   UMaps::CreateDepthStencilView( pD3DDevice, m_Width, m_Height, &m_pDSViewOfOpacityDepthMap, &m_pSRViewOfOpacityDepthMap );

   // 定数バッファを作成する
   m_pConstantBuffers[0] = m_pGraphicsPipeline[0]->CreateConstantBuffer( pD3DDevice, nullptr, sizeof( ColoredStochasticShadowMaps::CBUFFER_PASS0 ), D3D11_CPU_ACCESS_WRITE );

   // 深度マップコピー用クラス
   m_pSRViewRenderer = NEW USRViewRenderer();
   m_pSRViewRenderer->Create( pD3DDevice, -1, 1, 1, -1 );

   // *******************************************************************************************************
   // 半透明メッシュのカラーおよび深度マップ作成
   // *******************************************************************************************************

   m_pGraphicsPipeline[1] = NEW UGraphicsPipeline();

   // ラスタライザーステートを作成する
   m_pGraphicsPipeline[1]->CreateRasterizerState( pD3DDevice, D3D11_CULL_MODE::D3D11_CULL_BACK );

   // 深度ステンシルステートを作成する( 深度バッファへの書き込みを行わない )
   m_pGraphicsPipeline[1]->CreateDepthStencilState( pD3DDevice, TRUE, D3D11_DEPTH_WRITE_MASK::D3D11_DEPTH_WRITE_MASK_ZERO );

   // ブレンドステートを作成する
   BlendStateType[0] = UGraphicsPipeline::UEBLEND_STATE::DEPTH_TEST;
   m_pGraphicsPipeline[1]->CreateBlendState( pD3DDevice, BlendStateType, 1 );

   // シェーダーを作成する
#if defined(DEBUG) || defined(_DEBUG)
   m_pGraphicsPipeline[1]->CreateVertexShaderFromFile( pD3DDevice, _T("../HLSL/ColoredStochasticShadowMaps_Pass1.hlsl"), "ColoredStochasticShadowMaps_Pass1_VS_Main", layout, _countof( layout ) );
   m_pGraphicsPipeline[1]->CreatePixelShaderFromFile(  pD3DDevice, _T("../HLSL/ColoredStochasticShadowMaps_Pass1.hlsl"), "ColoredStochasticShadowMaps_Pass1_PS_Main" );
#else
   m_pGraphicsPipeline[1]->CreateVertexShaderFromMemory( pD3DDevice, (LPBYTE)g_ColoredStochasticShadowMaps_Pass1_VS_Main, sizeof( g_ColoredStochasticShadowMaps_Pass1_VS_Main ), layout, _countof( layout ) );
   m_pGraphicsPipeline[1]->CreatePixelShaderFromMemory(  pD3DDevice, (LPBYTE)g_ColoredStochasticShadowMaps_Pass1_PS_Main, sizeof( g_ColoredStochasticShadowMaps_Pass1_PS_Main ) );
#endif

   // カラーマップ
   UMaps::CreateRenderTargetView( pD3DDevice, DXGI_FORMAT_R16G16B16A16_FLOAT, m_Width, m_Height, &m_pRTViewOfTranslucentColorAndDepthMap, &m_pSRViewOfTranslucentColorAndDepthMap );

   // ノイズマップを作成する
   UMaps::CreateSRViewOfNoiseMap( pD3DDevice, m_Width, m_Height, DXGI_FORMAT_R32_FLOAT, &m_pSRViewOfTNoiseMap );

   // 定数バッファを作成する
   m_pConstantBuffers[1] = m_pGraphicsPipeline[1]->CreateConstantBuffer( pD3DDevice, nullptr, sizeof( ColoredStochasticShadowMaps::CBUFFER_PASS1 ), D3D11_CPU_ACCESS_WRITE );

   // サンプラーステートを作成する
   m_pSamplerStateOfNoiseMap = USamplers::CreateSamplerState( pD3DDevice, D3D11_TEXTURE_ADDRESS_CLAMP, D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT );

   // *******************************************************************************************************
   // カメラビューでレンダリング
   // *******************************************************************************************************

   m_pGraphicsPipeline[2] = NEW UGraphicsPipeline();

   // ラスタライザーステートを作成する
   m_pGraphicsPipeline[2]->CreateRasterizerState( pD3DDevice, D3D11_CULL_MODE::D3D11_CULL_BACK );

   // 深度ステンシルステートを作成する
   m_pGraphicsPipeline[2]->CreateDepthStencilState( pD3DDevice, TRUE, D3D11_DEPTH_WRITE_MASK::D3D11_DEPTH_WRITE_MASK_ALL );

   // ブレンドステートを作成する
   BlendStateType[0] = UGraphicsPipeline::UEBLEND_STATE::ALIGNMENT;
   m_pGraphicsPipeline[2]->CreateBlendState( pD3DDevice, BlendStateType, 1 );

   // シェーダーを作成する
#if defined(DEBUG) || defined(_DEBUG)
   m_pGraphicsPipeline[2]->CreateVertexShaderFromFile( pD3DDevice, _T("../HLSL/ColoredStochasticShadowMaps_Pass2.hlsl"), "ColoredStochasticShadowMaps_Pass2_VS_Main", layout, _countof( layout ) );
   m_pGraphicsPipeline[2]->CreatePixelShaderFromFile(  pD3DDevice, _T("../HLSL/ColoredStochasticShadowMaps_Pass2.hlsl"), "ColoredStochasticShadowMaps_Pass2_PS_Main" );
#else
   m_pGraphicsPipeline[2]->CreateVertexShaderFromMemory( pD3DDevice, (LPBYTE)g_ColoredStochasticShadowMaps_Pass2_VS_Main, sizeof( g_ColoredStochasticShadowMaps_Pass2_VS_Main ), layout, _countof( layout ) );
   m_pGraphicsPipeline[2]->CreatePixelShaderFromMemory(  pD3DDevice, (LPBYTE)g_ColoredStochasticShadowMaps_Pass2_PS_Main, sizeof( g_ColoredStochasticShadowMaps_Pass2_PS_Main ) );
#endif
 
   // 定数バッファを作成する
   m_pConstantBuffers[2] = m_pGraphicsPipeline[2]->CreateConstantBuffer( pD3DDevice, nullptr, sizeof( ColoredStochasticShadowMaps::CBUFFER_PASS2 ), D3D11_CPU_ACCESS_WRITE );

   // サンプラーステートを作成する
   m_pSamplerStateOfNoiseMap = USamplers::CreateSamplerState( pD3DDevice, D3D11_TEXTURE_ADDRESS_CLAMP, D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT );
}

void ColoredStochasticShadowMaps::BeginPass( ID3D11DeviceContext* pD3DDeviceContext, UINT Pass,
                                   XMFLOAT4* pVecLightPos, XMMATRIX* pMatLightProj, XMMATRIX* pMatCameraView, XMMATRIX* pMatCameraProj )
{
   if (m_Pass != -1)
   {
      throw(UException(-1, _T("ColoredStochasticShadowMaps::BeginPass()はCreate()またはEndPass()実行後に使用してください")));
   }

   m_Pass = (int)Pass;

   switch( m_Pass )
   {
   case 0:
      {
         pD3DDeviceContext->OMGetRenderTargets( _countof( m_pOldRTView ), m_pOldRTView, &m_pOldDSView );

         // 不透明メッシュの深度値を出力
         pD3DDeviceContext->OMSetRenderTargets( 0, nullptr, m_pDSViewOfOpacityDepthMap );

         pD3DDeviceContext->RSGetViewports( &m_ViewportCount, nullptr );
         pD3DDeviceContext->RSGetViewports( &m_ViewportCount, &m_pOldViewport[0] );

         // ビューポートを切り替える。
         D3D11_VIEWPORT Viewport[1];
         Viewport[0].TopLeftX = 0;
         Viewport[0].TopLeftY = 0;
         Viewport[0].Width    = (FLOAT)m_Width;
         Viewport[0].Height   = (FLOAT)m_Height;
         Viewport[0].MinDepth = 0.0f;
         Viewport[0].MaxDepth = 1.0f;
         pD3DDeviceContext->RSSetViewports( 1, Viewport );

         // 深度バッファをクリアする。
         pD3DDeviceContext->ClearDepthStencilView( m_pDSViewOfOpacityDepthMap, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0  );

         m_VecLightPos = *pVecLightPos;

         m_MatLightView = XMMatrixLookAtLH(XMLoadFloat3((XMFLOAT3*)&m_VecLightPos), XMLoadFloat3(&XMFLOAT3(0, 0, 0)), XMLoadFloat3(&XMFLOAT3(0, 1, 0)));
         m_MatLightProj = (*pMatLightProj);

         m_MatCameraView = XMMatrixIdentity();
         m_MatCameraProj = XMMatrixIdentity();
      }
      break;

   case 1:
      {
         pD3DDeviceContext->OMGetRenderTargets( _countof( m_pOldRTView ), m_pOldRTView, &m_pOldDSView );

         // カラーマップに出力
         pD3DDeviceContext->OMSetRenderTargets( 1, &m_pRTViewOfTranslucentColorAndDepthMap, m_pDSViewOfOpacityDepthMap );

         pD3DDeviceContext->RSGetViewports( &m_ViewportCount, nullptr );
         pD3DDeviceContext->RSGetViewports( &m_ViewportCount, &m_pOldViewport[0] );

         // ビューポートを切り替える。
         D3D11_VIEWPORT Viewport[1];
         Viewport[0].TopLeftX = 0;
         Viewport[0].TopLeftY = 0;
         Viewport[0].Width    = (FLOAT)m_Width;
         Viewport[0].Height   = (FLOAT)m_Height;
         Viewport[0].MinDepth = 0.0f;
         Viewport[0].MaxDepth = 1.0f;
         pD3DDeviceContext->RSSetViewports( 1, Viewport );

         pD3DDeviceContext->PSSetShaderResources( 1, 1, &m_pSRViewOfTNoiseMap );
         pD3DDeviceContext->PSSetSamplers( 1, 1, &m_pSamplerStateOfNoiseMap );
      }
      break;

   case 2:
      {
         pD3DDeviceContext->PSSetShaderResources( 1, 1, &m_pSRViewOfTranslucentColorAndDepthMap );
         pD3DDeviceContext->PSSetSamplers( 1, 1, &m_pSamplerStateOfColorAndDepthMap );

         m_MatCameraView = (*pMatCameraView);
         m_MatCameraProj = (*pMatCameraProj);
      }
      break;

   default:
      throw(UException(-1, _T("ColoredStochasticShadowMaps::BeginPass()で無効なPassが指定されました")));
   }

   // 各種ステートを設定する
   m_pGraphicsPipeline[m_Pass]->SetRasterizerState( pD3DDeviceContext );
   m_pGraphicsPipeline[m_Pass]->SetDepthStencilState( pD3DDeviceContext );
   m_pGraphicsPipeline[m_Pass]->SetBlendState( pD3DDeviceContext );

   // 各種グラフィックパイプラインを設定
   m_pGraphicsPipeline[m_Pass]->SetVertexShader( pD3DDeviceContext );
   m_pGraphicsPipeline[m_Pass]->SetHullShader( pD3DDeviceContext );
   m_pGraphicsPipeline[m_Pass]->SetDomainShader( pD3DDeviceContext );
   m_pGraphicsPipeline[m_Pass]->SetGeometryShader( pD3DDeviceContext );
   m_pGraphicsPipeline[m_Pass]->SetPixelShader( pD3DDeviceContext );
}

void ColoredStochasticShadowMaps::SetConstantBuffers( ID3D11DeviceContext* pD3DDeviceContext, XMMATRIX* pMatWorld )
{
   HRESULT hr = E_FAIL;

   // ライトビューのビュー行列を作成
   XMMATRIX matLView = XMMatrixLookAtLH( XMLoadFloat3( (XMFLOAT3*)&m_VecLightPos ), XMLoadFloat3( &XMFLOAT3( 0, 0, 0 ) ), XMLoadFloat3( &XMFLOAT3( 0, 1, 0 ) ) );

   // ライトビューのワールド行列とビュー行列と射影行列
   XMMATRIX matLightWorldViewProj = XMMatrixTranspose( *pMatWorld * matLView * m_MatLightProj );

   switch( m_Pass )
   {
   case 0:
      {
         // 定数バッファを作成する
         D3D11_MAPPED_SUBRESOURCE mappedResource;
         if( FAILED( hr = pD3DDeviceContext->Map( m_pConstantBuffers[m_Pass], 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource ) ) )
            throw( UException( -1, _T("ColoredStochasticShadowMaps::SetConstantBuffers()でエラーが発生しました。Map()が失敗しました。") ) );
         ColoredStochasticShadowMaps::CBUFFER_PASS0* cbuffer = (ColoredStochasticShadowMaps::CBUFFER_PASS0*)mappedResource.pData;
         ::CopyMemory( &cbuffer->matLightWorldViewProj, &matLightWorldViewProj, sizeof( XMMATRIX ));
         pD3DDeviceContext->Unmap( m_pConstantBuffers[m_Pass], 0 );

         // 定数バッファを設定
         pD3DDeviceContext->VSSetConstantBuffers( 0, 1, &m_pConstantBuffers[m_Pass] );
      }
      break;

   case 1:
      {
         // 定数バッファをロックする
         D3D11_MAPPED_SUBRESOURCE mappedResource;
         if( FAILED( hr = pD3DDeviceContext->Map( m_pConstantBuffers[m_Pass], 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource ) ) )
            throw( UException( -1, _T("ColoredStochasticShadowMaps::SetConstantBuffers()でエラーが発生しました。Map()が失敗しました。") ) );
         ColoredStochasticShadowMaps::CBUFFER_PASS1* cbuffer = (ColoredStochasticShadowMaps::CBUFFER_PASS1*)mappedResource.pData;
         ::CopyMemory( &cbuffer->matLightWorldViewProj, &matLightWorldViewProj, sizeof( XMMATRIX ) );
         pD3DDeviceContext->Unmap( m_pConstantBuffers[m_Pass], 0 );

         // 定数バッファを設定
         pD3DDeviceContext->VSSetConstantBuffers( 0, 1, &m_pConstantBuffers[m_Pass] );
         pD3DDeviceContext->PSSetConstantBuffers( 0, 1, &m_pConstantBuffers[m_Pass] );
      }
      break;

   case 2:
      {
         // カメラビュー
         XMMATRIX matCameraWorldViewProj = XMMatrixTranspose( *pMatWorld * m_MatCameraView * m_MatCameraProj );

         // 定数バッファをロックする
         D3D11_MAPPED_SUBRESOURCE mappedResource;
         if( FAILED( hr = pD3DDeviceContext->Map( m_pConstantBuffers[m_Pass], 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource ) ) )
            throw( UException( -1, _T("ColoredStochasticShadowMaps::SetConstantBuffers()でエラーが発生しました。Map()が失敗しました。") ) );
         ColoredStochasticShadowMaps::CBUFFER_PASS2* cbuffer = (ColoredStochasticShadowMaps::CBUFFER_PASS2*)mappedResource.pData;
         ::CopyMemory( &cbuffer->matLightWorldViewProj, &matLightWorldViewProj, sizeof( XMMATRIX ) );
         ::CopyMemory( &cbuffer->matCameraWorldViewProj, &matCameraWorldViewProj, sizeof( XMMATRIX ) );
         pD3DDeviceContext->Unmap( m_pConstantBuffers[m_Pass], 0 );

         // 定数バッファを設定
         pD3DDeviceContext->VSSetConstantBuffers( 0, 1, &m_pConstantBuffers[m_Pass] );
         pD3DDeviceContext->PSSetConstantBuffers( 0, 1, &m_pConstantBuffers[m_Pass] );
      }
      break;
   }
}

void ColoredStochasticShadowMaps::EndPass( ID3D11DeviceContext* pD3DDeviceContext )
{
   switch( m_Pass )
   {
   case 0:
      {
         // 深度値が格納されているR成分をコピーする
         pD3DDeviceContext->OMSetRenderTargets( 1, &m_pRTViewOfTranslucentColorAndDepthMap, nullptr );
         int SrcRGB[4] = { 0, 0, 0, 0 };
         m_pSRViewRenderer->SetSRView( m_pSRViewOfOpacityDepthMap, SrcRGB );
         m_pSRViewRenderer->Render( pD3DDeviceContext );

         // レンダーターゲットビューと深度ステンシルビューとビューポートを戻す

         pD3DDeviceContext->OMSetRenderTargets( _countof( m_pOldRTView ), m_pOldRTView, m_pOldDSView );
         for( UINT i=0; i<_countof( m_pOldRTView ); i++ )
            SAFE_RELEASE( m_pOldRTView[i] );
         SAFE_RELEASE( m_pOldDSView );

         pD3DDeviceContext->RSSetViewports( m_ViewportCount, m_pOldViewport );
      }
      break;

   case 1:
      {
         // レンダーターゲットビューと深度ステンシルビューとビューポートを戻す
         pD3DDeviceContext->OMSetRenderTargets( _countof( m_pOldRTView ), m_pOldRTView, m_pOldDSView );
         for( UINT i=0; i<_countof( m_pOldRTView ); i++ )
            SAFE_RELEASE( m_pOldRTView[i] );
         SAFE_RELEASE( m_pOldDSView );

         pD3DDeviceContext->RSSetViewports( m_ViewportCount, m_pOldViewport );

         ID3D11ShaderResourceView* pSRViewNull[] = { nullptr, nullptr };
         pD3DDeviceContext->PSSetShaderResources( 0, _countof( pSRViewNull ), pSRViewNull );
      }
      break;

   case 2:
      {

      }
      break;
   }

   m_Pass = -1;
}

ノイズマップはプロシージャル生成しました。

---WallMesh.h---  ↑


#ifndef WALLMESH_H
#define WALLMESH_H

#include "../Common/UCommon.h"
#include "../Common/UDirect3D11.h"
#include "../Common/UException.h"
#include "../Common/UD3DMeshDataCreater.h"

#include "../Common/XNAMath/xnamath.h"

class WallMesh
{
private:
   // 頂点バッファ
   ID3D11Buffer* m_pVertexBuffer;

   // インデックスバッファ
   ID3D11Buffer* m_pIndexBuffer;

   // シェーダーリソースビュー
   ID3D11ShaderResourceView* m_pSRView;

   // サンプラーステート
   ID3D11SamplerState* m_pSamplerState;

   XMMATRIX m_MatWorld[2];

   ULONG m_VertexCount;
   ULONG m_IndexCount;

public:
   WallMesh();
   virtual ~WallMesh();
   void Invalidate();
   void CreateMesh( ID3D11Device* pD3DDevice );
   void NextFrame();
   inline UINT GetMaxMeshCount(){ return _countof( m_MatWorld ); };
   inline XMMATRIX* GetMatWorld( UINT index ){ return &m_MatWorld[index]; };
   void Render( ID3D11DeviceContext* pD3DDeviceContext );
};

#endif

---WallMesh.cpp---  ↑


#include "../../Header/Mesh/WallMesh.h"

WallMesh::WallMesh()
{
   m_pVertexBuffer = nullptr;
   m_pIndexBuffer = nullptr;
   m_pSRView = nullptr;
   m_pSamplerState = nullptr;
   m_VertexCount = 0;
   m_IndexCount = 0;
}

WallMesh::~WallMesh()
{
   Invalidate();
}

void WallMesh::Invalidate()
{
   m_IndexCount = 0;
   m_VertexCount = 0;
   SAFE_RELEASE( m_pSamplerState );
   SAFE_RELEASE( m_pSRView );
   SAFE_RELEASE( m_pIndexBuffer );
   SAFE_RELEASE( m_pVertexBuffer );
}

void WallMesh::CreateMesh( ID3D11Device* pD3DDevice )
{
   UD3DMeshDataCreater::VERTEX vertex[] = {
      XMFLOAT3(1.0f, 1.0f, 1.0f), XMFLOAT3(0.0f, 0.0f, 1.0f), XMFLOAT2(0.0f, 0.0f),  // 0
      XMFLOAT3(-1.0f, 1.0f, 1.0f), XMFLOAT3(0.0f, 0.0f, 1.0f), XMFLOAT2(1.0f, 0.0f),  // 1
      XMFLOAT3(1.0f, -1.0f, 1.0f), XMFLOAT3(0.0f, 0.0f, 1.0f), XMFLOAT2(0.0f, 1.0f),  // 2
      XMFLOAT3(-1.0f, -1.0f, 1.0f), XMFLOAT3(0.0f, 0.0f, 1.0f), XMFLOAT2(1.0f, 1.0f),  // 3
      XMFLOAT3(1.0f, 1.0f, -1.0f), XMFLOAT3(0.0f, 0.0f, -1.0f), XMFLOAT2(0.0f, 0.0f),  // 4
      XMFLOAT3(-1.0f, 1.0f, -1.0f), XMFLOAT3(0.0f, 0.0f, -1.0f), XMFLOAT2(1.0f, 0.0f),  // 5
      XMFLOAT3(1.0f, -1.0f, -1.0f), XMFLOAT3(0.0f, 0.0f, -1.0f), XMFLOAT2(0.0f, 1.0f),  // 6
      XMFLOAT3(-1.0f, -1.0f, -1.0f), XMFLOAT3(0.0f, 0.0f, -1.0f), XMFLOAT2(1.0f, 1.0f),  // 7
         };

   m_VertexCount = _countof( vertex );

   // 頂点バッファを作成する
   m_pVertexBuffer = UBuffers::CreateVertexBuffer( pD3DDevice, vertex, sizeof( vertex ), 0 );
  
   UINT Indexes[] = { 1, 0, 3, 0, 2, 3,  // 奥面
                      4, 5, 6, 5, 7, 6,  // 手前面
                      0, 4, 2, 4, 6, 2,  // 右面
                      5, 1, 7, 1, 3, 7,  // 左面
                      0, 1, 4, 1, 5, 4,  // 上面
                      3, 2, 7, 2, 6, 7   // 下面
   };

   m_IndexCount = _countof( Indexes );

   // インデックスバッファを作成する
   m_pIndexBuffer = UBuffers::CreateIndexBuffer( pD3DDevice, Indexes, sizeof( Indexes ), 0 );

   // サンプラーステートを作成する
   m_pSamplerState = USamplers::CreateSamplerState( pD3DDevice, D3D11_TEXTURE_ADDRESS_WRAP );

   // テクスチャーを作成する
   UMaps::CreateSRViewFromDDSFile( pD3DDevice, _T("../Resource/Glass.dds"), &m_pSRView );
}

void WallMesh::NextFrame()
{
   XMMATRIX matScaling, matRotationZ, matTranslate;

   matScaling = XMMatrixScaling( 70, 50, 2 );

   matRotationZ = XMMatrixRotationZ( 0.0f );
   matTranslate = XMMatrixTranslation( 0.0f, 25.0f, 50.0f );
   m_MatWorld[0] = matRotationZ * matScaling * matTranslate;

   matRotationZ = XMMatrixRotationZ( XM_PI / 2 );
   matTranslate = XMMatrixTranslation( 0.0f, 25.0f, -50.0f );
   m_MatWorld[1] = matRotationZ * matScaling * matTranslate;
}

void WallMesh::Render( ID3D11DeviceContext* pD3DDeviceContext )
{
   // 頂点バッファ設定
   UINT stride = sizeof( UD3DMeshDataCreater::VERTEX );
   UINT offset = 0;
   pD3DDeviceContext->IASetVertexBuffers( 0, 1, &m_pVertexBuffer, &stride, &offset );

   // インデックスバッファを設定
   pD3DDeviceContext->IASetIndexBuffer( m_pIndexBuffer, DXGI_FORMAT_R32_UINT, 0 );

   // プリミティブ タイプおよびデータの順序に関する情報を設定
   pD3DDeviceContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST );

   // ピクセルシェーダーのサンプラーステートを設定する
   pD3DDeviceContext->PSSetSamplers( 0, 1, &m_pSamplerState );

   // デカールマップを設定する
   pD3DDeviceContext->PSSetShaderResources( 0, 1, &m_pSRView );

   // 描画
   pD3DDeviceContext->DrawIndexed( m_IndexCount, 0, 0 );
}

テクスチャーは適当に作成してください。

---main.cpp---  ↑


#include "../Header/Common/UCommon.h"
#include "../Header/Common/UException.h"
#include "../Header/Common/UDirect3D11.h"
#include "../Header/Common/UDebugFont.h"
#if defined(DEBUG) || defined(_DEBUG)
#include "../Header/Common/USRViewRenderer.h"
#endif
#include "../Header/Shader/ColoredStochasticShadowMaps.h"
#include "../Header/Mesh/PlaneMesh.h"
#include "../Header/Mesh/WallMesh.h"

// アプリケーション名
TCHAR* AppName = _T("Direct3D11 Colored Stochastic Shadow Maps");

// Direct3D関連の自作クラス
UDirect3D11* g_pDirect3D11 = nullptr;

ColoredStochasticShadowMaps* g_pColoredStochasticShadowMaps = nullptr;

PlaneMesh* g_pPlaneMesh = nullptr;
WallMesh* g_pWallMesh = nullptr;

UFPS* g_pFPS = nullptr;

#if defined(DEBUG) || defined(_DEBUG)
USRViewRenderer* g_pSRViewRenderer = nullptr;
#endif

DWORD g_Width = 640, g_Height = 480;
float g_LZFar = 950.0f, g_LZNear = 10.0f;

// カメラビュー行列
XMMATRIX g_MatCameraView = XMMatrixIdentity();

// カメラービュー射影行列
XMMATRIX g_MatCameraProj = XMMatrixPerspectiveFovLH( XM_PI / 5.0f, (float)g_Width / (float)g_Height, 10.0f, 1000.0f );

// ライトビューは距離計算が正しくできるように正射影行列にする
XMMATRIX g_MatLightProj = XMMatrixOrthographicLH( 300.0f, 300.0f, g_LZNear, g_LZFar );

// 平行光源の位置ベクトル
XMFLOAT4 g_VecLightPos = XMFLOAT4( 130.0f, 100.0f, -170.0f, 0 );

// メモリ解放
void Invalidate()
{
#if defined(DEBUG) || defined(_DEBUG)
   SAFE_DELETE( g_pSRViewRenderer );
#endif

   SAFE_DELETE( g_pFPS );
   SAFE_DELETE( g_pColoredStochasticShadowMaps );
   SAFE_DELETE( g_pPlaneMesh );
   SAFE_DELETE( g_pWallMesh );
   SAFE_DELETE( g_pDirect3D11 );
}

// ウィンドウプロシージャ
LRESULT CALLBACK WndProc( HWND hWnd, UINT msg, UINT wParam, LONG lParam )
{
   switch( msg )
   {
   case WM_KEYUP:
      // アプリ終了
      if( wParam == VK_ESCAPE )
         ::DestroyWindow( hWnd );
      break;

   case WM_DESTROY:
      ::PostQuitMessage(0);
      break;

   default:
      return ::DefWindowProc( hWnd, msg, wParam, lParam );
   }

   return 0L;
}

// Direct3Dの作成
void CreateDirect3D( HINSTANCE hInstance )
{
   DXGI_MODE_DESC* pModeDescArray = nullptr;

   __try
   {
      DXGI_MODE_DESC  ModeDesc;
      UINT num;

      // ディスプレイモード一覧の数を取得する
      g_pDirect3D11->GetDisplayMode( nullptr, &num );

      pModeDescArray = NEW DXGI_MODE_DESC[num];
      // ディスプレイモード一覧を取得する
      g_pDirect3D11->GetDisplayMode( pModeDescArray, &num );

      bool find = false;
      for( UINT i=0; i<num; i++ )
      {
         // 適切な解像度のディスプレイモードを検索する
         if( pModeDescArray[i].Width == g_Width && pModeDescArray[i].Height == g_Height )
         {
            find = true;
            ::CopyMemory( &ModeDesc, &pModeDescArray[i], sizeof( DXGI_MODE_DESC ) );
            break;
         }
      }

      if( find == false )
         throw( UException( -1, _T("InitDirect3D()でエラーが発生しました。適切なディスプレイモードの解像度を取得できません。") ) );

      // ウィンドウの作成およびDirect3D の作成
      g_pDirect3D11->CreateDirect3D11( AppName, hInstance, WndProc, &ModeDesc, TRUE, TRUE );

      // FPS描画クラス
      g_pFPS->CreateMesh( g_pDirect3D11->m_pD3DDevice );

#if defined(DEBUG) || defined(_DEBUG)
      g_pSRViewRenderer->Create( g_pDirect3D11->m_pD3DDevice, 1.0f - 400.0f / (float)g_Width, 1.0f, 1.0f, 1.0f - 400.0f / (float)g_Height );
#endif
   }
   __finally
   {
      SAFE_DELETE_ARRAY( pModeDescArray );
   }
}

void CreateGraphicePipeline()
{
   DWORD Width = 512, Height = 512;

   g_pColoredStochasticShadowMaps->Create( g_pDirect3D11->m_pD3DDevice, Width, Height );
}

// メッシュを作成する
void CreateMesh()
{
   g_pPlaneMesh = NEW PlaneMesh();
   g_pPlaneMesh->CreateMesh( g_pDirect3D11->m_pD3DDevice );

   g_pWallMesh = NEW WallMesh();
   g_pWallMesh->CreateMesh( g_pDirect3D11->m_pD3DDevice );
}

void CreateResource( HINSTANCE hInstance )
{
   // Direct3D 関連自作クラスのインスタンスを作成
   // CreateDirect3D()関数内でインスタンスの作成を行うと、C2712 エラーが発生するのでここで行う。
   g_pDirect3D11 = NEW UDirect3D11();

   g_pColoredStochasticShadowMaps = NEW ColoredStochasticShadowMaps();

   g_pFPS = NEW UFPS();

#if defined(DEBUG) || defined(_DEBUG)
   g_pSRViewRenderer = NEW USRViewRenderer();
#endif

   // Direct3Dの作成
   CreateDirect3D( hInstance );

   // グラフィックパイプラインリソースの作成
   CreateGraphicePipeline();

   // リソースの作成
   CreateMesh();
}

void NextFrame()
{
   // ビュー行列
   if( GetKeyState( VK_UP ) & 0x8000 )
      g_MatCameraView *= XMMatrixTranslation( 0, 0, -0.5f );
   if( GetKeyState( VK_DOWN ) & 0x8000 )
      g_MatCameraView *= XMMatrixTranslation( 0, 0, 0.5f );
   if( GetKeyState( VK_RIGHT ) & 0x8000 )
      g_MatCameraView *= XMMatrixRotationY( -0.004f );
   if( GetKeyState( VK_LEFT ) & 0x8000 )
      g_MatCameraView *= XMMatrixRotationY( 0.004f );
   if( GetKeyState( 'Q' ) & 0x8000 )
      g_MatCameraView *= XMMatrixRotationX( 0.004f );
   if( GetKeyState( 'A' ) & 0x8000 )
      g_MatCameraView *= XMMatrixRotationX( -0.004f );

   g_pFPS->NextFrame();

   g_pPlaneMesh->NextFrame();
   g_pWallMesh->NextFrame();
}

// 描画処理
HRESULT Render()
{
   HRESULT hr = E_FAIL;
   
   static float ClearColor[4] = { 0.3f, 0.3f, 1.0f, 1.0f };

    // バックバッファをクリアする。
   g_pDirect3D11->ClearBackBuffer( ClearColor ); 

   // 深度バッファをクリアする。
   g_pDirect3D11->ClearDepthStencilView( D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0 );

   g_pColoredStochasticShadowMaps->BeginPass( g_pDirect3D11->m_pD3DDeviceContext, 0, &g_VecLightPos, &g_MatLightProj, &g_MatCameraView, &g_MatCameraProj );
   g_pColoredStochasticShadowMaps->SetConstantBuffers( g_pDirect3D11->m_pD3DDeviceContext, g_pPlaneMesh->GetMatWorld() );
   g_pPlaneMesh->Render( g_pDirect3D11->m_pD3DDeviceContext );
   g_pColoredStochasticShadowMaps->EndPass( g_pDirect3D11->m_pD3DDeviceContext );

   g_pColoredStochasticShadowMaps->BeginPass( g_pDirect3D11->m_pD3DDeviceContext, 1, &g_VecLightPos, &g_MatLightProj, &g_MatCameraView, &g_MatCameraProj );
   for( UINT i=0; i<g_pWallMesh->GetMaxMeshCount(); i++ )
   {
      g_pColoredStochasticShadowMaps->SetConstantBuffers( g_pDirect3D11->m_pD3DDeviceContext, g_pWallMesh->GetMatWorld(i) );
      g_pWallMesh->Render( g_pDirect3D11->m_pD3DDeviceContext );
   }
   g_pColoredStochasticShadowMaps->EndPass( g_pDirect3D11->m_pD3DDeviceContext );

   g_pColoredStochasticShadowMaps->BeginPass( g_pDirect3D11->m_pD3DDeviceContext, 2, &g_VecLightPos, &g_MatLightProj, &g_MatCameraView, &g_MatCameraProj );
   g_pColoredStochasticShadowMaps->SetConstantBuffers( g_pDirect3D11->m_pD3DDeviceContext, g_pPlaneMesh->GetMatWorld() );
   g_pPlaneMesh->Render( g_pDirect3D11->m_pD3DDeviceContext );
   for( UINT i=0; i<g_pWallMesh->GetMaxMeshCount(); i++ )
   {
      g_pColoredStochasticShadowMaps->SetConstantBuffers( g_pDirect3D11->m_pD3DDeviceContext, g_pWallMesh->GetMatWorld(i) );
      g_pWallMesh->Render( g_pDirect3D11->m_pD3DDeviceContext );
   }
   g_pColoredStochasticShadowMaps->EndPass( g_pDirect3D11->m_pD3DDeviceContext );

#if defined(DEBUG) || defined(_DEBUG)
   int SrcRGB[4] = { 0, 1, 2, 3 };
   g_pSRViewRenderer->SetSRView( g_pColoredStochasticShadowMaps->GetTranslucentColorMap(), SrcRGB );
   g_pSRViewRenderer->Render( g_pDirect3D11->m_pD3DDeviceContext );
#endif

   g_pFPS->Render( g_pDirect3D11->m_pD3DDeviceContext );

   // レンダリングされたイメージをユーザーに表示。
   if( FAILED( hr = g_pDirect3D11->Present( 0, 0 ) ) )
      throw( UException( hr, _T("IDXGISwapChain::Present()が失敗しました") ) );

   return hr;
}
 
// メイン関数
int APIENTRY _tWinMain( HINSTANCE hInstance,
                        HINSTANCE,
                        LPTSTR,
                        INT )
{
   // メモリリーク検出
//   _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF | CRTDBG_CHECK_ALWAYS_DF );
   _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF | _CRTDBG_CHECK_EVERY_1024_DF );

   MSG msg = {0};

   try
   {
      CreateResource( hInstance );

      ::ShowWindow( g_pDirect3D11->m_hWnd, SW_SHOW );
      ::UpdateWindow( g_pDirect3D11->m_hWnd );

      // メッセージループ
      do
      { 
         if( ::PeekMessage( &msg, 0, 0, 0, PM_REMOVE ) )
         {
            ::TranslateMessage(&msg); 
            ::DispatchMessage(&msg); 
         }
         else
         {
            NextFrame();
            Render();
         }
      }while( msg.message != WM_QUIT );
   }
   catch( UException ex )
   {
      ::MessageBox( nullptr, ex.m_pErrorStr, _T("エラー"), MB_OK );
   }

   Invalidate();

   ::UnregisterClass( AppName, hInstance );

   return msg.wParam;
}

ようやく終わりが見えてきた...


web拍手 by FC2

Prev Top Next

inserted by FC2 system