11

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

任何帮助,将不胜感激。

PS我正在考虑像素着色器中的RWTexture2D或RWStructuredBuffer。一点背景知识:我需要这两个图像在计算着色器中进行进一步处理。这带来了同步的一个附带问题:由于像素着色器(与计算着色器不同)一次写入每个像素,我怎么知道像素着色器何时完成并告诉计算着色器开始图像后处理?

4

1 回答 1

20

您需要使用 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

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

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;
}

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

对于像素/计算着色器同步,您不能在同一设备上同时运行像素着色器和计算着色器,因此当您的绘制调用完成时,纹理已准备好在计算中用于调度。

于 2012-10-04T15:18:42.640 回答