2
votes


I'm implementing deferred rendering/shading for the very first time I ran into some problems which I'm having trouble to solve on my own :/.

When rendering the geometry pass and deferred pass together I get this wierd looking output enter image description here

I'm using a green clear color in the beginning of my deferred pass before setting topology, input layout etc.. So that's where the green comes from. I'm not sure why the output image is split in half though.

My main problem is however successfully passing the render targets from my geometry pass as shader resource views to my deferred shader. This is the result from my geometry shader enter image description here

So judging by the output image I've seen to managed the transform to the correct space right?

In my geometry pass I set my render targets

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

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

In the deferred pass I set them as shader resource views

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

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

In my deferred shader I register them

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

And sample them

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;

To get the exact same output that the geometry pass gave I write

return float4( worldPosSample, 1.0f );

But all I get is that black and green split image that I posted. To debug this I put some if-statements that return a color if one of elements in a float3 sample was 0.0f and ALL of the elements are 0.0f! Am I really setting the gbuffer render targets as shader resource views correctly?

My understanding was that when a gbuffer contains an ID3D11ShaderResourceView* and an ID3D11RenderTargetView* and the ID3D11Texture2D*, used for creating both, is created with the D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE bind flag that when the render target view is used, then its content is automatically "copied" to the gbuffer shader resource view which later can be used as input in a shader.

Feel free to correct me and/or broaden my horizons on the subject. Any suggestions on my problem? Thank you!

1
The data is never copied anywhere. The actual bits are the same memory, you just have to different ways to 'view' the same data. You can't use the same physical buffer as both input and output in the same rendering pass, but you should think of the RT and SRV here as both being the same physical bit of memory.Chuck Walbourn

1 Answers

0
votes

I figured out what I was doing wrong!

The black and green split image was a result from sampling in the deferred shader with incorrect UV-coordinates. I made the mistake of simply passing the geometry again and sampling with its texture coordinates.

The solution was to define a very simple quad and a new vertex buffer to store it in

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

The quad has its normal pointed in the negatize Z-axis so it's orientation is just as the textures that was produced in the geometry pass. I also created a new ID3D11InputLayout* containing only POSITION, NORMAL and TEXCOORD for the deferred pass as well as changed the topology to D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP since my geometry pass use tesselation.

This is the final output :) enter image description here