在directx 11中一次渲染渲染到多个纹理

l3u*_*fly 7 directx-11 render-to-texture pixel-shader compute-shader

我正在尝试使用C++ directx 11 SDK一次渲染到两个纹理.我希望一个纹理包含结果图像的每个像素的颜色(我在渲染3D场景时通常在屏幕上看到的颜色),另一个纹理包含每个像素和深度的法线(3个浮点数用于法线和1个浮点数)深度).现在,我能想到的是创建两个渲染目标并将第一遍渲染为颜色,第二遍分别传递法线和深度到每个渲染目标.然而,这似乎是浪费时间,因为我可以在第一遍中获得每个像素的颜色,法线和深度的信息.那么有没有办法用像素着色器以某种方式输出两个纹理?

任何帮助,将不胜感激.

PS我在想象像素着色器中的RWTexture2D或RWStructuredBuffer.一点背景:我需要两个图像在计算着色器中进一步处理.这引出了同步的一个侧面问题:由于像素着色器(与计算着色器不同)一次一个地写入每个像素,我如何知道像素着色器何时完成并告诉计算着色器开始图像后处理?

cat*_*ier 13

您需要使用MRT(多个渲染目标)一次渲染.

您可以使用OMSetRenderTargets将两个目标绑定为输出

http://msdn.microsoft.com/en-us/library/windows/desktop/ff476464(v=vs.85).aspx

http://hieroglyph3.codeplex.com/(DefferedRendering)中有一个示例,它会显示如何一次写入两个纹理.

这是一个小样本:

ID3D11DeviceContext* deviceContext; //Your immediate context

ID3D11RenderTargetView* m_pRenderViews[2]; //Not more than D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT (8)
m_pRenderViews[0] = pRTV1; //First target
m_pRenderViews[1] = pRTV2; //second target

deviceContext->OMSetRenderTargets(2, &m_pRenderViews[0], NULL); //NULL means no depth stencil attached
Run Code Online (Sandbox Code Playgroud)

然后,您的像素着色器将需要输出结构而不是单个颜色:

struct PS_OUTPUT
{
    float4 Color: SV_Target0;
    float4 Normal: SV_Target1;
};

PS_OUTPUT PS(float4 p: SV_Position, float2 uv : TEXCOORD0)
{
      PS_OUTPUT output;
      output.Color = //Set first output
      output.Normal= //Set second output
      return output;
}
Run Code Online (Sandbox Code Playgroud)

同样在DirectX11中,您不需要将深度写入普通缓冲区,您只需使用深度缓冲区即可.

对于Pixel/Compute着色器同步,您无法在同一设备上同时运行像素着色器和计算着色器,因此当绘制调用完成后,纹理就可以在计算中用于调度.