我正在为我的一个DirectX 11.0项目做好一切准备,以获得延迟渲染管道。但是,在像素着色器中对深度缓冲区进行采样时,我遇到了很多麻烦。
首先我定义深度纹理及其着色器资源视图:
stdin
这是我的渲染功能的相关部分:
scanf()
在这个临时实现中,firstVS_和secondVS_是相同的,它们唯一的功能是完成所有转换并将数据传递给PS。
最后,这里有第一个PS_和第二个PS _:
scanf("%d"
所以,我的实际问题是:
1)所有这些代码编译没有任何问题,但是当我对深度缓冲区进行采样时,它只是变成黑色。我读到这可能是因为你的深度和在您想要对深度缓冲区进行采样时由"456"
绑定的模板视图。我解决了这个问题,但缓冲区仍然是黑色的。我检查了图形调试器,没有成功。那么,我的深度缓冲区是不能正确编写的,还是我采用了错误的方式? firstPS_工作正常。
2)说到抽样,我正在使用的书只是说“我们将使用点采样器”,但我不知道究竟是什么意思。现在我只是使用一个标准的纹理贴图采样器,但还有其他我应该采样的东西吗?
3)此外,本书在secondPS_中使用scanf()
函数,但是当我尝试它时,它抱怨“表达式无法映射到像素着色器指令集”。本书中 D3D11_TEXTURE2D_DESC depthTexDesc;
ZeroMemory(&depthTexDesc, sizeof(depthTexDesc));
depthTexDesc.Width = nWidth;
depthTexDesc.Height = nHeight;
depthTexDesc.Format = DXGI_FORMAT_R32_TYPELESS;
depthTexDesc.Usage = D3D11_USAGE_DEFAULT;
depthTexDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL | D3D11_BIND_SHADER_RESOURCE;
depthTexDesc.MipLevels = 1;
depthTexDesc.ArraySize = 1;
depthTexDesc.SampleDesc.Count = 1;
depthTexDesc.SampleDesc.Quality = 0;
depthTexDesc.CPUAccessFlags = 0;
depthTexDesc.MiscFlags = 0;
hresult = d3dDevice_->CreateTexture2D(&depthTexDesc, nullptr, &depthTexture_);
D3D11_DEPTH_STENCIL_VIEW_DESC DSVDesc;
ZeroMemory(&DSVDesc, sizeof(DSVDesc));
DSVDesc.Format = DXGI_FORMAT_D32_FLOAT;
DSVDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
DSVDesc.Texture2D.MipSlice = 0;
hresult = d3dDevice_->CreateDepthStencilView(depthTexture_, &DSVDesc, &depthView_);
D3D11_SHADER_RESOURCE_VIEW_DESC gbDepthTexDesc;
ZeroMemory(&gbDepthTexDesc, sizeof(gbDepthTexDesc));
gbDepthTexDesc.Format = DXGI_FORMAT_R32_FLOAT;
gbDepthTexDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
gbDepthTexDesc.Texture2D.MipLevels = 1;
gbDepthTexDesc.Texture2D.MostDetailedMip = -1;
d3dDevice_->CreateShaderResourceView(depthTexture_, &gbDepthTexDesc, &gbDepthView_);
是错误,还是我的GPU(D3D功能级别11.0)谁不明白这是什么? float clearColor[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
d3dContext_->ClearRenderTargetView(backBufferTarget_, clearColor);
d3dContext_->ClearDepthStencilView(depthView_, D3D11_CLEAR_DEPTH, 1.0f, 0);
// GBuffer packing pass (in the future): /////////////////////////////////////////
d3dContext_->OMSetRenderTargets(1, &backBufferTarget_, depthView_);
unsigned int nStride = sizeof(Vertex);
unsigned int nOffset = 0;
d3dContext_->IASetInputLayout(inputLayout_);
d3dContext_->IASetVertexBuffers(0, 1, &vertexBuffer_, &nStride, &nOffset);
d3dContext_->IASetIndexBuffer(indexBuffer_, DXGI_FORMAT_R32_UINT, 0);
d3dContext_->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
d3dContext_->VSSetShader(firstVS_, 0, 0);
d3dContext_->PSSetShader(firstPS_, 0, 0);
d3dContext_->DrawIndexed(nIndexCount_, 0, 0);
d3dContext_->OMSetRenderTargets(1, &backBufferTarget_, nullptr);
d3dContext_->VSSetShader(secondVS_, 0, 0);
d3dContext_->PSSetShader(secondPS_, 0, 0);
d3dContext_->PSGetShaderResources(0, 1, &gbDepthView_);
d3dContext_->PSSetSamplers(0, 1, &colorMapSampler_);
d3dContext_->DrawIndexed(nIndexCount_, 0, 0);
swapChain_->Present(0, 0);
是否足以满足我的目的? // firstPS_
float4 main(PS_Input frag) : SV_TARGET
{
return float4(1.0f, 1.0f, 1.0f, 1.0f);
}
// secondPS_
Texture2D<float> depthMap_ : register(t0);
SamplerState colorSampler_ : register(s0);
float4 main(PS_Input frag) : SV_TARGET
{
float4 psOut;
psOut.xyz = depthMap_.Sample(colorSampler_, frag.tex0).xxx;
psOut.w = 1.0f;
return psOut;
}
的原始用法是在深度缓冲区中的对象周围创建轮廓。
4)我试图让secondVS_只绘制一个全屏四边形,但是FXC抱怨我使用D3D11DeviceContext::OMSetRenderTargets()
为“无效”,说我的类型应该是完整的,即使它已经是。我在某处读到SamplerState.Gather()
只能由管道中的第一个VS使用。这是问题吗?在这种特殊情况下如何解决这个问题?在我目前效率低下的解决方案中,问题是由UV引起的吗?
答案 0 :(得分:1)
1)您已经调用了PSGetShaderResources而不是PSSetShaderResources。此外,MostDetailedMip应为0而不是-1。
2)A&#34;点采样器&#34;只是一个纹理采样器,其FILTER字段设置为D3D11_FILTER_MIN_MAG_MIP_POINT。
3)Gather是Texture2D上的一个函数,而不是您所说的SamplerState。
4)如果使用vs_4_0进行编译,则会出现此错误,请尝试使用vs_5_0。