0

我正在从 Introduction_to_3D_Game_Programming_with_Directx_11 学习 dx11。没有 msaa 一切正常。当我启用它时,我的 .fx 和 C++ 代码将无法正常工作。是否有人也经历过这种情况以及如何处理这种情况?

代码前:

Texture2D gTexture1;
float4 BLEND_PS(VertexOut_SV pin) :SV_TARGET
{
    float4 texColor = float4(0.0f, 0.0f, 0.0f, 0.0f);
    texColor = gTexture1.Sample(SamAnisotropic, pin.Tex);
    return texColor;
}

因为我无法将使用 msaa 创建的纹理绑定到纹理 2D,所以我每次都打开 msaa。

代码后:

Texture2DMS<float4> gTexture1;
float4 BLEND_PS(VertexOut_SV pin) :SV_TARGET
{
    float4 texColor = float4(0.0f, 0.0f, 0.0f, 0.0f);
    texColor = gTexture1.Load(int2(pin.Tex.x*1400, pin.Tex.y*900), 0);
    return texColor;
}

但是 texColor 不是我想要的正确像素。如何使用 msaa 对 SRV 进行采样?如何将没有 msaa 的 UAV 转换为带 msaa 的 SRV?

以及如何使用相应的 hlsl 代码在 C++ 游戏代码中启用和禁用 msaa?我必须为彼此保留不同的 hlsl 吗?

4

1 回答 1

1

对于“标准”MSAA 使用,您可以执行以下操作:

  1. 创建交换链和渲染跟踪视图时,将DXGI_SWAP_CHAIN_DESC.SampleDesc.Count或 设置DXGI_SWAP_CHAIN_DESC1.SampleDesc.Count为 2、4、8 等。

  2. 创建深度缓冲区/模板时,您需要对D3D11_TEXTURE2D_DESC.SampleDesc.Count.

  3. 创建渲染目标视图时,您需要使用D3D11_RTV_DIMENSION_TEXTURE2DMS(或传递nullptr视图描述,使其与资源完全匹配)

  4. 创建深度缓冲区/模板视图时,您需要使用D3D11_DSV_DIMENSION_TEXTURE2DMS(或传递nullptr视图描述,使其与资源完全匹配)

  5. 渲染时,您需要使用D3D11_RASTERIZER_DESC.MultisampleEnable设置为 TRUE 的光栅化器状态。

另请参阅DirectX Tool Kit的简单渲染教程

样本数

根据 Direct3D 功能级别,特定呈现目标格式需要一些 MSAA 样本计数。使用可以CheckFormatSupport用来验证渲染目标格式是否支持 MSAA:

UINT formatSupport = 0;
if (FAILED(device->CheckFormatSupport(m_backBufferFormat, &formatSupport)))
{
    throw std::exception("CheckFormatSupport");
}

UINT flags = D3D11_FORMAT_SUPPORT_MULTISAMPLE_RESOLVE
     | D3D11_FORMAT_SUPPORT_MULTISAMPLE_RENDERTARGET;

if ( (formatSupport & flags) != flags )
{
    // error
}

然后,您可以使用CheckMultisampleQualityLevels来验证样本计数是否受支持。此代码查找特定格式的最高支持 MSAA 级别计数:

for (m_sampleCount = D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT;
    m_sampleCount > 1; m_sampleCount--)
{
    UINT levels = 0;
    if (FAILED(device->CheckMultisampleQualityLevels(m_backBufferFormat,
            m_sampleCount, &levels)))
        continue;

    if ( levels > 0)
        break;
}

if (m_sampleCount < 2)
{
    // error
}

您还可以验证要使用的深度/模板格式支持D3D11_FORMAT_SUPPORT_DEPTH_STENCIL | D3D11_FORMAT_SUPPORT_MULTISAMPLE_RENDERTARGET

翻转样式模式

上述技术仅适用于较旧的“bit-blt”风格翻转模式 DXGI_SWAP_EFFECT_DISCARDDXGI_SWAP_EFFECT_SEQUENTIAL. 对于 UWP 和 DirectX 12,您必须使用,DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL否则DXGI_SWAP_EFFECT_FLIP_DISCARD如果您尝试创建 SampleCount > 1 的后台缓冲区,则会失败。

在这种情况下,您创建一个 SampleCount 为 1 的后缓冲区,并创建您自己的 MSAA Render Target 2D 纹理。您的渲染目标视图指向您的 MSAA 渲染目标,并且在您从 MSAA 渲染目标Present调用ResolveSubresource到 backbuffer 之前。这与 DXGI 为您在“幕后”使用较旧的翻转模型所做的事情完全相同。

对于 gamma-correct 渲染(也就是当您使用以 结尾的 backbuffer 格式时_SRGB),较新的翻转样式要求您使用非 SRGB 等效的 backbuffer 格式,否则交换链创建将失败。您改为在渲染目标视图上设置 SRGB 格式。

于 2016-10-28T16:37:00.700 回答