延迟渲染:将渲染目标作为着色器资源视图传递给着色器时出现问题

Defered rendering : Problems when passing Render Targets as Shader Resource Views to shader


我第一次 运行 实施延迟 rendering/shading 解决一些我自己无法解决的问题:/。

同时渲染几何通道和延迟通道时,我得到了这个看起来很奇怪的输出

在设置拓扑、输入布局等之前,我在延迟通道的开头使用了绿色透明色。这就是绿色的来源。我不确定为什么输出图像被分成两半。

然而,我的主要问题是成功地将渲染目标从我的几何通道作为着色器资源视图传递到我的延迟着色器。这是我的几何着色器的结果

所以从输出图像来看,我已经将 t运行sform 管理到正确的 space 对吗?

在我的几何通道中,我设置了我的渲染目标

ID3D11RenderTargetView* renderTargetsToSet[] = { mGBuffers[0]->RenderTargetView(), 
                                                 mGBuffers[1]->RenderTargetView(), 
                                                 mGBuffers[2]->RenderTargetView(),
                                                 mGBuffers[3]->RenderTargetView() };

mDeviceContext->OMSetRenderTargets( NUM_GBUFFERS, renderTargetsToSet, mDepthStencilView );

在延迟通道中,我将它们设置为着色器资源视图

ID3D11ShaderResourceView* viewsToSet[] = { mGBuffers[0]->mShaderResourceView,
                                           mGBuffers[1]->mShaderResourceView,
                                           mGBuffers[2]->mShaderResourceView,
                                           mGBuffers[3]->mShaderResourceView };

mDeviceContext->PSSetShaderResources( 0, 4, viewsToSet );

在我的延迟着色器中注册它们

Texture2D       worldPosTexture     : register( t0 );
Texture2D       normalTexture       : register( t1 );
Texture2D       diffuseTexture      : register( t2 );
Texture2D       specularTexture     : register( t3 );

并对它们进行采样

float3 worldPosSample   = worldPosTexture.Sample( samplerState, input.texCoord ).xyz;
float3 normalSample     = normalTexture.Sample( samplerState, input.texCoord ).xyz;
float3 diffuseSample    = diffuseTexture.Sample( samplerState, input.texCoord ).xyz;
float3 specularSample   = specularTexture.Sample( samplerState, input.texCoord ).xyz;

为了获得与几何传递给的完全相同的输出,我写了

return float4( worldPosSample, 1.0f );

但我得到的只是我发布的黑色和绿色分割图像。 为了对此进行调试,我放置了一些 if 语句,如果 float3 样本中的一个元素为 0.0f 并且 ALL 元素为 0.0f,则 return 颜色! 我是否真的将 gbuffer 渲染目标正确设置为着色器资源视图?

我的理解是,当 gbuffer 包含 ID3D11ShaderResourceView* 和 ID3D11RenderTargetView* 以及用于创建两者的 ID3D11Texture2D* 时,是使用 D3D11_BIND_RENDER_TARGET | 创建的D3D11_BIND_SHADER_RESOURCE 绑定标志,当使用渲染目标视图时,其内容会自动 "copied" 到 gbuffer 着色器资源视图,稍后可以用作着色器的输入。

欢迎指正 and/or 开阔我的视野。 对我的问题有什么建议吗?谢谢!

我知道我做错了什么了!

黑色和绿色分割图像是在延迟着色器中使用不正确的 UV 坐标 进行采样的结果。我犯了一个错误,只是再次传递几何体并使用其纹理坐标进行采样。

解决方案是定义一个非常简单的四边形和一个新的顶点缓冲区来存储它

vertices[0].position = XMFLOAT3( -1.0f,  1.0f, 0.0f );  vertices[0].normal = XMFLOAT3( 0.0f, 0.0f, -1.0f );     vertices[0].texCoord = XMFLOAT2( 0.0f, 0.0f );
vertices[1].position = XMFLOAT3(  1.0f,  1.0f, 0.0f );  vertices[1].normal = XMFLOAT3( 0.0f, 0.0f, -1.0f );     vertices[1].texCoord = XMFLOAT2( 1.0f, 0.0f );
vertices[2].position = XMFLOAT3( -1.0f, -1.0f, 0.0f );  vertices[2].normal = XMFLOAT3( 0.0f, 0.0f, -1.0f );     vertices[2].texCoord = XMFLOAT2( 0.0f, 1.0f );
vertices[3].position = XMFLOAT3(  1.0f, -1.0f, 0.0f );  vertices[3].normal = XMFLOAT3( 0.0f, 0.0f, -1.0f );     vertices[3].texCoord = XMFLOAT2( 1.0f, 1.0f );

四边形的法线指向负 Z 轴,因此它的方向与几何通道中生成的纹理一样。我还为延迟通道创建了一个仅包含 POSITIONNORMALTEXCOORD 的新 ID3D11InputLayout*,并将拓扑更改为 D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP,因为我的几何通道使用镶嵌。

这是最终输出:)