使用DirectX 12工具包,我能够成功编译和运行各个MSAA和HDR教程示例。然而,当我将MSAA和HDR组件的相关代码组合到一个Game.cpp文件中时,编译失败,并显示调试层消息:
D3D12错误:ID3D12CommandList::ResolveSubresource:指定的格式与源资源不兼容。格式:R10G10B10A2_UNORM,源资源格式:R16G16B16A16_FLOAT[RRESOURCE_MANIPULATION ERROR#878:RESOLESUBRESOURCE_INVALID_Format]
我正在使用SDR显示器的HDR示例代码,因此需要应用色调映射。关于调用的顺序,在尝试解析MSAA渲染目标之前,我会调用以结束HDR场景:
// 3d rendering completed
m_hdrScene->EndScene(commandList);
if (m_msaa)
{
// Resolve the MSAA render target.
//PIXBeginEvent(commandList, PIX_COLOR_DEFAULT, L"Resolve");
auto backBuffer = m_deviceResources->GetRenderTarget();
...
然后,在MSAA解析块之后,我将音调映射语句放置如下:
// Unbind depth/stencil for sprites (UI)
auto rtvDescriptor = m_deviceResources->GetRenderTargetView();
commandList->OMSetRenderTargets(1, &rtvDescriptor, FALSE, nullptr);
// set texture descriptor heap in prep for sprite drawing
commandList->SetDescriptorHeaps(static_cast<UINT>(std::size(heaps)), heaps);
// apply tonemapping to hdr scene
switch (m_deviceResources->GetColorSpace())
{
default:
m_toneMap->Process(commandList);
break;
...
我发现在设置用于绘制2D精灵的描述符堆(在3D场景上(之前尝试色调映射会导致错误:
D3D12错误:CGraphicsCommandList::SetGraphicsRootDescriptorTable:包含句柄0x80000253a82ff205的描述符堆(0x0000025428203230:"DescriptorHeap"(与当前设置的描述符堆0x000002542820 3540:"EffectTextureFactory"不同。[执行错误#708:SET_DESCRIPTOR_TABLE_INVALID]D3D12:BREAK为上一条消息启用,该消息为:[ERROR EXECTION#708:SET_DESCRIPTOR_TABLE_INVALID]
我承认这是第一次尝试将HDR和MSAA结合起来,但我担心这些功能在DirectX 12中可能不兼容和/或互斥。我理解为什么在MSAA解决过程中会出现资源兼容性问题,因为我们需要为HDR使用浮点渲染目标。我应该注意,如果我通过将m_MSAA布尔值设置为false跳过MSAA代码块,我的程序将使用HDR正确运行和渲染。
期待任何人的建议。如果需要足够的代码或有关程序的其他详细信息,我很乐意更新我的帖子。
为了使用4xMSAA成功渲染HDR场景,我进行了以下修订:
-
在CreateWindowSizeDependentResources((中,MSAA渲染目标(和视图(的定义格式与HDR渲染纹理相同:
// Create an MSAA render target. D3D12_RESOURCE_DESC msaaRTDesc = CD3DX12_RESOURCE_DESC::Tex2D( //m_deviceResources->GetBackBufferFormat(), m_hdrScene->GetFormat(), // set matching format to HDR target (_R16G16B16A16_FLOAT) backBufferWidth, backBufferHeight, 1, // This render target view has only one texture. 1, // Use a single mipmap level 4 // <--- Use 4x MSAA ); ...
-
下一个主要变化是Render((,其中MSAA对HDR目标的解析发生在结束HDR场景渲染之后和色调映射过程之前:
// Resolve the MSAA render target. auto backBuffer = m_deviceResources->GetRenderTarget(); auto hdrBuffer = m_hdrScene->GetResource(); // HDR destination texture { D3D12_RESOURCE_BARRIER barriers[2] = { // transition msaa texture from target to resolve source CD3DX12_RESOURCE_BARRIER::Transition( m_msaaRenderTarget.Get(), D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_RESOLVE_SOURCE), // transition hdr texture from pixel shader resource to resolve destination CD3DX12_RESOURCE_BARRIER::Transition( hdrBuffer, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, D3D12_RESOURCE_STATE_RESOLVE_DEST) }; commandList->ResourceBarrier(2, barriers); } //commandList->ResolveSubresource(backBuffer, 0, m_msaaRenderTarget.Get(), 0, // m_deviceResources->GetBackBufferFormat()); // resolve MSAA to the single sample 16FP resource destination commandList->ResolveSubresource(hdrBuffer, 0, m_msaaRenderTarget.Get(), 0, m_hdrScene->GetFormat()); // prepare backbuffer for 2D sprite drawing, typically rendered without MSAA { D3D12_RESOURCE_BARRIER barriers[2] = { // transition hdr texture from resolve destination back to p.s resource CD3DX12_RESOURCE_BARRIER::Transition( hdrBuffer, D3D12_RESOURCE_STATE_RESOLVE_DEST, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE), // transition backbuffer from Present to render target (for sprite drawing after the MSAA resolve) CD3DX12_RESOURCE_BARRIER::Transition( backBuffer, D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_RENDER_TARGET) }; commandList->ResourceBarrier(2, barriers); } ... do tone mapping ... do 2D sprite drawing
输出为传统1080p显示器(无HDR10或V-Sync(。LHS屏幕捕捉是没有MSAA的HDR场景,而RHS捕捉显示了4xMSAA对3D线框对象的平滑效果;地球模型和三角形广告牌。cat和"Hello World"文本是在MSAA解析和色调映射后绘制到后缓冲区的2D精灵。
再次感谢@ChuckWalbourn为我指明了正确的方向,我期待着使用DirectX工具包推进我的项目。
ResolveSubresource
无法进行从16fp到10:10:10:2 HDR10的转换。
通常你需要:
- 在高动态范围(线性颜色空间(中渲染到MSAA浮点
- 将MSAA解析为单采样浮点。(许多游戏选择使用高级软件抗锯齿技术作为这一过程的一部分,如FXAA、SMAA等。(
- 执行色调映射和Rec.2020颜色空间从浮点到10:10:10:2的转换
- 显示HDR10
渲染UI有时发生在步骤3之前,有时发生在之后。如果以前做过,你通常必须"放大"UI颜色,使其脱颖而出。
有关技术详细信息,请参阅SimpleMSAA DX12和SimpleHDR DX12示例。
DirectX工具包包括一个PostProcess
类,它可以执行HDR10色调映射。请参阅本教程。