一. Shader 使用的资源
Shader Mode 4.0 开始支持更多种类的资源,比如 tbuffer 和 Buffer ,Shader Mode 5 又加入了 StructuredBuffer 等。我们今天就来说说他们直接的区别。下面的代码和说明是以 D3D11 为基础的。
二. 在 Shader 中的定义和使用 cbuffer / tbuffer / Buffer / Texture / StructuredBuffer
-
cbuffer
// 在 Shader 中的定义 Constant Buffer
cbuffer cbMatrices
{
float4x4 g_matWorld_CBuffer[1024];
};
// 在 Shader 中使用 Constant Buffer
float4x4 matData=g_matWorld_CBuffer[uiIndex];
-
tbuffer
// 在 Shader 中定义 T Buffer
tbuffer tbMatrices
{
float4x4 g_matWorld_TBuffer[1024];
};
// 在 Shader 中使用 T Buffer
float4x4 matData=g_matWorld_TBuffer[uiIndex];
-
Buffer
// 在 Shader 中定义 Buffer
Buffer<float4> g_matWorld_Buffer;
// 在 Shader 中使用 Buffer
uiIndex*=4;
float4 f4Row1=g_matWorld_Buffer.Load(uiIndex);
float4 f4Row2=g_matWorld_Buffer.Load(uiIndex+1);
float4 f4Row3=g_matWorld_Buffer.Load(uiIndex+2);
float4 f4Row4=g_matWorld_Buffer.Load(uiIndex+3);
float4x4 matData=float4x4(f4Row1,f4Row2,f4Row3,f4Row4);
-
Texture
// 在 Shader 中定义 Texture
Texture1D g_matWorld_Texture1D;
// 在 Shader 中使用 Texture
uiIndex*=4;
float4 f4Row1=g_matWorld_Texture1D.Load(float2(uiIndex, 0));
float4 f4Row2=g_matWorld_Texture1D.Load(float2(uiIndex+1,0));
float4 f4Row3=g_matWorld_Texture1D.Load(float2(uiIndex+2,0));
float4 f4Row4=g_matWorld_Texture1D.Load(float2(uiIndex+3,0));
float4x4 matData=float4x4(f4Row1,f4Row2,f4Row3,f4Row4);
-
StructuredBuffer
// 在 Shader 中定义 StructuredBuffer
struct my_struct
{
float4x4 m_matWorld;
};
StructuredBuffer<my_struct> g_matWorld_StructBuffer;
// 在 Shader 中使用 StructuredBuffer
float4x4 matData=g_matWorld_StructBuffer[uiIndex].m_matWorld;
三. 在程序中反射和创建 cbuffer / tbuffer / Buffer / Texture / StructuredBuffer
-
cbuffer
反射 cbuffer 的时候 D3D_SHADER_INPUT_TYPE 的值是 D3D_SIT_CBUFFER.
创建 cbuffer 的时候使用 D3D11_BIND_CONSTANT_BUFFER 参数进行 CreateBuffer.
-
tbuffer
反射 tbuffer 的时候 D3D_SHADER_INPUT_TYPE 的值是 D3D_SIT_TBUFFER.
创建 tbuffer 的时候使用 D3D11_BIND_SHADER_RESOURCE 参数进行 CreateBuffer. 然后使用 D3D11_SRV_DIMENSION_BUFFER 创建 Shader Resource View.
-
Buffer
反射 Buffer 的时候 D3D_SHADER_INPUT_TYPE 的值是 D3D_SIT_TEXTURE,D3D_SRV_DIMENSION 的值是 D3D_SRV_DIMENSION_BUFFER.
Buffer 对象支持 ID3D11Buffer 和 ID3D11Texture* 两种资源,可使用 D3D11_BIND_SHADER_RESOURCE 参数进行 CreateBuffer 或 CreateTexture1D. 然后使用 D3D11_SRV_DIMENSION_BUFFER 创建 Shader Resource View.
-
Texture
反射 Texture 的时候 D3D_SHADER_INPUT_TYPE 的值是 D3D_SIT_TEXTURE.
创建 Texture 的时候使用 D3D11_BIND_SHADER_RESOURCE 参数进行 CreateTexture1D. 然后使用 D3D11_SRV_DIMENSION_TEXTURE1D 创建 Shader Resource View.
-
StructuredBuffer
反射 StructuredBuffer 的时候 D3D_SHADER_INPUT_TYPE 的值是 D3D_SIT_STRUCTURED,D3D_SRV_DIMENSION 的值是 D3D_SRV_DIMENSION_BUFFER.
创建 StructuredBuffer 的时候可以使用 D3D11_BIND_SHADER_RESOURCE 参数进行 CreateBuffer. 然后使用 D3D11_SRV_DIMENSION_BUFFER 创建 Shader Resource View.
四. 总结
首先从资源创建来看,cbuffer / tbuffer / StructuredBuffer 的资源创建方法都是 CreateBuffer ,只是参数有所差别(D3D11_BIND_CONSTANT_BUFFER 和 D3D11_BIND_SHADER_RESOURCE),而 Texture 是使用 CreateTexture1D 来创建的,这就说明 cbuffer / tbuffer / StructuredBuffer 的本质都是 Buffer。而 Buffer 即可使用 Buffer 也可使用 Texture。另外,tbuffer / Buffer / Texture 除了创建资源本身之外还需要创建 SRV 才能使用.
其次从 Shader 使用资源来看,cbuffer 和 tbuffer 除了定义的关键字之外没有区别,使用起来都是用索引取数组中的数据。而 Buffer 和 Texture 都需要使用 Load 函数来取数据。要注意的是 Texture 的 Load 方法,虽然我们声明和创建的 Texture 是 1D Texture ,但是在 Load 的时候需要二维的纹理坐标,因为这个是真正的采样操作。
本文介绍了Direct3D 11中Shader使用的资源类型,如cbuffer、tbuffer、Buffer、Texture和StructuredBuffer。详细讨论了它们在Shader中的定义、创建、反射和使用方法,特别强调了它们之间的区别和联系,揭示了cbuffer、tbuffer、StructuredBuffer本质上都是Buffer,而Buffer和Texture则需要额外的SRV创建才能使用。
2410

被折叠的 条评论
为什么被折叠?



