我目前正在D3D项目中工作,想实现定向阴影映射。我按照Microsoft Guide进行了所有设置,但这只是行不通。
我已经创建了一个2D纹理对象,一个深度模具视图和一个着色器资源视图,并使用以下描述进行设置:
D3D11_TEXTURE2D_DESC shadowMapDesc;
ZeroMemory(&shadowMapDesc, sizeof(D3D11_TEXTURE2D_DESC));
shadowMapDesc.Width = width;
shadowMapDesc.Height = height;
shadowMapDesc.MipLevels = 1;
shadowMapDesc.ArraySize = 1;
shadowMapDesc.Format = DXGI_FORMAT_R24G8_TYPELESS;
shadowMapDesc.SampleDesc.Count = 1;
shadowMapDesc.SampleDesc.Quality = 0;
shadowMapDesc.Usage = D3D11_USAGE_DEFAULT;
shadowMapDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL | D3D11_BIND_SHADER_RESOURCE;
shadowMapDesc.CPUAccessFlags = 0;
shadowMapDesc.MiscFlags = 0;
ID3D11Device& d3ddev = dev.getD3DDevice();
uint32_t *initData = new uint32_t[width * height];
ZeroMemory(initData, sizeof(uint32_t) * width * height);
D3D11_SUBRESOURCE_DATA data;
ZeroMemory(&data, sizeof(D3D11_SUBRESOURCE_DATA));
data.pSysMem = initData;
data.SysMemPitch = sizeof(uint32_t) * width;
data.SysMemSlicePitch = 0;
HRESULT hr = d3ddev.CreateTexture2D(&shadowMapDesc, &data, &texture_);
D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc;
ZeroMemory(&depthStencilViewDesc, sizeof(D3D11_DEPTH_STENCIL_VIEW_DESC));
depthStencilViewDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
depthStencilViewDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
depthStencilViewDesc.Texture2D.MipSlice = 0;
hr = d3ddev.CreateDepthStencilView(texture_, &depthStencilViewDesc, &stencilView_);
D3D11_SHADER_RESOURCE_VIEW_DESC shaderResourceViewDesc;
ZeroMemory(&shaderResourceViewDesc, sizeof(D3D11_SHADER_RESOURCE_VIEW_DESC));
shaderResourceViewDesc.Format = DXGI_FORMAT_R24_UNORM_X8_TYPELESS;
shaderResourceViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
shaderResourceViewDesc.Texture2D.MipLevels = 1;
shaderResourceViewDesc.Texture2D.MostDetailedMip = 0;
hr = d3ddev.CreateShaderResourceView(texture_, &shaderResourceViewDesc, &shaderView_);
在这些步骤之间,还进行了其他错误检查,但所有创建功能均成功返回。然后,我使用以下功能绑定纹理,渲染场景并取消绑定纹理:
void D3DDepthTexture2D::bindAsTarget(D3DDevice& dev)
{
dev.getDeviceContext().ClearDepthStencilView(stencilView_, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
// Bind target
dev.getDeviceContext().OMSetRenderTargets(0, 0, stencilView_);
// Set viewport
dev.setViewport(static_cast<float>(width_), static_cast<float>(height_), 0.0f, 0.0f);
}
void D3DDepthTexture2D::unbindAsTarget(D3DDevice& dev, float width, float height)
{
// Unbind target
dev.resetRenderTarget();
// Reset viewport
dev.setViewport(width, height, 0.0f, 0.0f);
}
我的“渲染到深度纹理”例程基本上是这样的(删除了所有不必要的细节):
camera = buildCameraFromLight(light);
setCameraCBuffer(camera);
bindTexture();
activateShader();
for(Object j : objects) {setTransformationCBuffer(j); renderObject(j);}
deactivateShader();
unbindTexture();
从光源的角度将场景渲染到正常的渲染目标(屏幕)会生成正确的图像(既是实际图像,也只是渲染深度值)。我使用了一个简单的顶点着色器,该顶点着色器仅转换了顶点,而一个像素着色器根本不执行任何操作,或者返回了深度值(我尝试了这两个方法,由于我们不在乎颜色缓冲区,因此不会改变最终结果)
清除纹理并将其渲染后,我将其渲染到屏幕的四边形上,但我得到的只是一个红色正方形-深度值为1.0f,即清除纹理的值。我真的无所适从,我尝试了一切,通过在线教程实施了每种可能的解决方案,或者自己改变了一切,但是没有任何帮助。这是我已经检查过的所有内容的列表:
我真的不知道怎么回事,我已经尝试调试了好几个小时。我希望这里有人可以给我有关我做错了什么或我可以尝试解决的问题的任何建议。我在Direct3D11中使用C ++ 11。
注意:我无法使用NSight或任何Visual Studio工具调试任何此类工具,因为它们目前似乎无法在我的系统上正常工作,并且我没有任何管理权限来修复其中的任何一个。我现在只需要处理它。我希望所给的信息和代码示例足以使我对我也可以尝试实现的工作有一个大概的了解。
谢谢。
答案 0 :(得分:1)
我让NSight可以工作并对其进行了调试。事实证明深度纹理是正确创建的,并填充了深度和模板数据,我只是忘记了所有深度信息都存储在第一个通道中,所以我忽略了g和b数据,并使用1.0作为a并起作用。使用g和b通道使整体变红(也许有人想添加它并解释原因)。
一旦我可以观察到着色器中存在的纹理,调试起来就会容易得多-我应该早先使用NSight或RenderDoc之类的调试工具。感谢@EgorShkorov的建议。