3

我想使用渲染目标作为 DirectX 11 中计算着色器的输入。我只需要读取计算着色器中的渲染目标,就我而言,我不必渲染计算着色器输出(尽管我确实有稍后在 CPU 中使用它,并且可能需要在额外的计算着色器通道中处理它。)

我看到评论说这是可能的,但我似乎找不到任何示例代码来显示如何在着色器资源视图中将渲染目标(Texture2D)用作计算着色器缓冲区。我尝试了许多选项,但无法创建计算机着色器需要作为输入的着色器资源视图。

指向示例代码片段的指针将不胜感激。

4

2 回答 2

2

您的资源确实需要具有着色器资源使用模式才能通过计算着色器读取:-对于标准渲染目标:D3D11_BIND_SHADER_RESOURCE -对于交换链:交换链描述中的 DXGI_USAGE_SHADER_INPUT。

然后像往常一样创建一个着色器资源视图。

也有可能(在某种程度上)让您的缓冲区也可以直接由计算着色器写入。在这种情况下,标志是 D3D11_BIND_UNORDERED_ACCESS 或 DXGI_USAGE_UNORDERED_ACCESS(请注意,这不适用于多重采样纹理)。

这是一个非常简单的计算着色器,它从 UV 坐标的纹理中读取样本:

RWStructuredBuffer<float4> rwbuffer;

//Render target previously rendered
Texture2D tex;

//Buffer containing uvs for sampling
 StructuredBuffer<float2> uv <string uiname="UV Buffer";>;

 SamplerState mySampler : IMMUTABLE
 {
     Filter = MIN_MAG_MIP_LINEAR;
     AddressU = Clamp;
     AddressV = Clamp;
 };

 [numthreads(1, 1, 1)]
 void CS( uint3 i : SV_DispatchThreadID)
 { 
//Read color and write to buffer
rwbuffer[i.x] = tex.SampleLevel(mySampler,uv[i.x],0);
 }

 technique11 Process
 {
pass P0
{
    SetComputeShader( CompileShader( cs_5_0, CS() ) );
}
 }

希望有帮助。

于 2013-09-16T12:13:17.273 回答
0

从纹理创建着色器资源视图的第一个要求是创建具有良好标志的纹理。标志是D3D11_BIND_SHADER_RESOURCE。在调用 CreateTexture2D 之前,它必须在描述绑定成员中设置。

如果渲染目标不是由您创建,而是来自交换链,则您无法将其绑定为 SRV。您将需要一个中间帧缓冲区并将其复制到帧末尾的后台缓冲区。

于 2013-09-15T08:31:18.243 回答