延迟渲染:将渲染目标作为着色器资源视图传递到着色器

时间:2015-07-24 19:07:01

标签: c++ directx-11 hlsl render-to-texture deferred-rendering


我正在实施延迟渲染/着色,这是我第一次遇到一些我自己无法解决的问题:/。

当渲染几何体传递和延迟传递时,我得到了这个看起来很奇怪的输出enter image description here

在设置拓扑,输入布局等之前,我在延迟传递的开头使用了绿色的清晰颜色。这就是绿色来自的地方。我不知道为什么输出图像被分成两半。

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

所以根据我看到的输出图像来判断将变换管理到正确的空间吗?

在我的几何传递中,我设置了渲染目标

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! 我是否真的将gbuffer渲染目标设置为着色器资源视图?

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

随意纠正我和/或开阔我对这个主题的视野。 对我的问题有任何建议吗?谢谢!

1 个答案:

答案 0 :(得分:0)

我弄清楚我做错了什么!

黑色和绿色分割图像是在延迟着色器中使用不正确的 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轴,因此它的方向就像几何中产生的纹理一样。我还为延迟传递创建了一个仅包含ID3D11InputLayout*POSITIONNORMAL的新TEXCOORD,并将拓扑更改为D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP,因为我的几何传递已使用镶嵌。

这是最终输出:) enter image description here

相关问题