前回書いた整数テクスチャの扱いに関して少々追加です。
レンダリングで更新する時は整数処理を行いますが、デバッグなどで
画面に描画する時は RenderTarget の 0.0~1.0 に変換する必要があると
下記エントリで書きました。
Direct3D 10 ShaderModel 4.0 で整数の世界
これを DirectX10(D3D10) の機能を使って自動化できます。
まずリソースの作成を DXGI_FORMAT_R8G8B8A8_UINT ではなく、
DXGI_FORMAT_R8G8B8A8_TYPELESS で宣言しておきます。
初期データの渡し方などは同じです。
D3D10_TEXTURE2D_DESC t2ddesc; t2ddesc.Format= DXGI_FORMAT_R8G8B8A8_TYPELESS; ~ ID3D10Texture2D* riTexture2D= NULL; iDevice->CreateTexture2D( &t2ddesc, &initdata, &riTexture2D );
その後、同じリソースから ShaderResourceView を 2個作成します。
こちらは型を明確にして UINT と UNORM にします。
// ShaderResourceView の作成 D3D10_SHADER_RESOURCE_VIEW_DESC srvdesc; srvdesc.Format= DXGI_FORMAT_R8G8B8A8_UINT; // 整数アクセス srvdesc.ViewDimension= D3D10_SRV_DIMENSION_TEXTURE2D; srvdesc.Texture2D.MostDetailedMip= 0; srvdesc.Texture2D.MipLevels= 1; iDevice->CreateShaderResourceView( riTexture2D, &srvdesc, iResourceViewUINT ); srvdesc.Format= DXGI_FORMAT_R8G8B8A8_UNORM; // 固定少数化 srvdesc.ViewDimension= D3D10_SRV_DIMENSION_TEXTURE2D; iDevice->CreateShaderResourceView( riTexture2D, &srvdesc, iResourceViewUNORM );
これでシェーダーからは、iResourceViewUINT 経由でアクセスすると
0~255 の整数値として読み込むことができ、iResourceViewUNORM で
アクセスすると、従来どおり 0~1.0 の少数値で受け取ることが
できるようになります。
例えばシェーダー側では次のように宣言しておきます。
Texture2DInputTextureUI; Texture2D InputTextureF;
エフェクトの変数設定はこんな感じで。
iEffect->GetVariableByName( "InputTextureUI" )->AsShaderResource()-> SetResource( iTextureBufferUINT ); iEffect->GetVariableByName( "InputTextureF" )->AsShaderResource()-> SetResource( iTextureBufferUNORM );
受け取るシェーダー側です。
// PixelShader で整数としてアクセスする場合 (0~255) float4 PS_Update( noperspective float4 Pos : SV_POSITION, noperspective float2 UV : TEXCOORD ) : SV_Target { float2 pixsize; InputTexture.GetDimensions( pixsize.x, pixsize.y ); uint2 uvpos= (uint2)( UV.xy * pixsize.xy ); return InputTextureUI.Load( uint3(uvpos.xy,0) )* (1.0f/255.0f); } // 浮動少数で受け取れるので乗算が不要 (0~1.0) float4 PS_View( noperspective float4 Pos : SV_POSITION, noperspective float2 UV : TEXCOORD ) : SV_Target { float2 pixsize; InputTexture.GetDimensions( pixsize.x, pixsize.y ); uint2 uvpos= (uint2)( UV.xy * pixsize.xy ); return InputTextureF.Load( uint3(uvpos.xy,0) ); }
便利です。さすがに良く考えられています。
注意点は、以前のエントリ で書いたように同一のリソースを複数の View
として設定するため、リソースが握られたままになって衝突が
おきやすいことです。
・Direct3D 10 HLSL Effect/FX リソース設定のはまり
上記の PixelShader では、UV を 0.0~1.0 に補間した値で受け取って
いるためテクスチャのサイズを乗算する処理が入っています。