【问题标题】:How do I send nearby pixel data to a Pixel-Shader in Direct3D 11?如何将附近的像素数据发送到 Direct3D 11 中的像素着色器?
【发布时间】:2015-05-25 18:24:43
【问题描述】:

我一直在阅读这些教程(我只允许使用 2 个链接):https://code.msdn.microsoft.com/Direct3D-Tutorial-Win32-829979ef

并通过 Direct3D 11 图形管道读取:https://msdn.microsoft.com/en-us/library/windows/desktop/ff476882%28v=vs.85%29.aspx

我目前有一个用 HLSL 编码的像素(又名片段)着色器,由以下代码组成:

//Pixel Shader input.
struct psInput
{
    float4 Position: SV_POSITION;
    float4 Color: COLOR;
};

//Pixel (aka. Fragment) Shader.
float4 PS(psInput input): SV_TARGET
{
    return input.Color;
}

我(想我)想做的是多重采样并访问像素着色器中每个像素的附近像素数据,以便我可以执行一种自定义抗锯齿,如 FXAA (http://developer.download.nvidia.com/assets/gamedev/files/sdk/11/FXAA_WhitePaper.pdf)。据我了解,我需要为每个渲染使用 PSSetShaderResources 将纹理传递给 HLSL,但除此之外我不知道。所以,我的问题是:

如何将附近的像素数据发送到 Direct3D 11 中的像素着色器?

除了我在教程中找到的标准“将一些 float4 传递给着色器”之外,能够做这种事情也对我理解 c++ 和 HLSL 如何相互交互非常有益。这似乎是 D3D 开发中最关键的方面,但我在网上找不到很多它的例子。

我考虑过传统的 MSAA(MultiSample Anti-Aliasing),但除了我需要使用“BitBlt”(位块传输)之外,我找不到任何关于如何在 D3D 11 中成功实现它的信息首先是模型交换链。 (请参阅 DXGI_SAMPLE_DESC1 和 DXGI_SAMPLE_DESC;只有计数为 1 和质量为 0(无 AA)会导致绘制内容。)此外,我想知道如何执行上述操作以进行一般理解,以防我需要它用于其他操作我项目的各个方面。不过,也欢迎有关如何在 D3D 11 中执行 MSAA 的答案。

请仅使用 D3D 11 和 HLSL 代码。

【问题讨论】:

    标签: c++11 graphics 3d directx sample


    【解决方案1】:

    要进行像 FXAA 这样的自定义抗锯齿,您需要将场景渲染到屏幕外渲染目标:

    -使用绑定标志D3D11_BIND_RENDER_TARGETD3D11_BIND_SHADER_RESOURCE 创建一个ID3D11Texture2D

    -为第一步中创建的纹理创建ID3D11ShaderResourceViewID3D11RenderTargetView

    -将场景渲染到步骤2中创建的ID3D11RenderTargetView

    -将后备缓冲区设置为渲染目标,并将步骤 2 中创建的ID3D11ShaderResourceView 绑定到正确的像素着色器插槽。

    -Render a fullscreen triangle covering the entire screen 您将能够在像素着色器中对包含场景的纹理进行采样(使用Load() 函数)


    当您尝试进行传统 MSAA 时,您是否记得设置 MultisampleEnable in the rasterizer state

    【讨论】:

    • 这一切都发生在我的 Draw 调用之后吗?是的,我启用了它,但无论如何都不会绘制任何内容。我难以理解的一件事是何时需要渲染到我的后台缓冲区和自定义渲染目标,以及我如何使此类事件在特定阶段发生。
    【解决方案2】:

    我再次回答我自己的问题,有点(从未使用过 FXAA...)。我在这里提供我的答案是为了对那些追随我脚步的人好。

    原来我错过了 MSAA 的深度模具视图。您希望 SampleCount 对于禁用的 MSAA 为 1U,对于 2XMSAA 为 2U,对于 4XMSAA 为 4U,对于 8XMSAA 为 8U 等。(使用ID3D11Device::CheckMultisampleQualityLevels 来“探测”可行的 MSAA 级别...)您几乎总是希望使用质量禁用 MSAA 的级别为 0U,启用的 MSAA 级别为 1U。

    以下是我的工作 MSAA 代码(您应该可以填写其余部分)。请注意,我使用了 DXGI_FORMAT_D24_UNORM_S8_UINT 和 D3D11_DSV_DIMENSION_TEXTURE2DMS,并且深度纹理和深度模板视图的 Format 值相同,SampleCount 和 SampleQuality 值相同。

    祝你好运!

        unsigned int SampleCount = 1U;
        unsigned int SampleQuality = (SampleCount > 1U ? 1U : 0U);
    
    
    
    
    //Create swap chain.
    
    IDXGIFactory2* dxgiFactory2 = nullptr;
    
    d3dResult = dxgiFactory->QueryInterface(__uuidof(IDXGIFactory2), reinterpret_cast<void**>(&dxgiFactory2));
    
    if (dxgiFactory2)
    {
        //DirectX 11.1 or later.
        d3dResult = D3DDevice->QueryInterface(__uuidof(ID3D11Device1), reinterpret_cast<void**>(&D3DDevice1));
    
        if (SUCCEEDED(d3dResult))
        {
            D3DDeviceContext->QueryInterface(__uuidof(ID3D11DeviceContext1), reinterpret_cast<void**>(&D3DDeviceContext1));
        }
    
        DXGI_SWAP_CHAIN_DESC1 swapChain;
        ZeroMemory(&swapChain, sizeof(swapChain));
        swapChain.Width = width;
        swapChain.Height = height;
        swapChain.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
        swapChain.SampleDesc.Count = SampleCount;
        swapChain.SampleDesc.Quality = SampleQuality;
        swapChain.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
        swapChain.BufferCount = 2U;
    
        d3dResult = dxgiFactory2->CreateSwapChainForHwnd(D3DDevice, w32Window, &swapChain, nullptr, nullptr, &SwapChain1);
    
        if (SUCCEEDED(d3dResult))
        {
            d3dResult = SwapChain1->QueryInterface(__uuidof(IDXGISwapChain), reinterpret_cast<void**>(&SwapChain));
        }
    
        dxgiFactory2->Release();
    }
    else
    {
        //DirectX 11.0.
        DXGI_SWAP_CHAIN_DESC swapChain;
        ZeroMemory(&swapChain, sizeof(swapChain));
        swapChain.BufferCount = 2U;
        swapChain.BufferDesc.Width = width;
        swapChain.BufferDesc.Height = height;
        swapChain.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
        swapChain.BufferDesc.RefreshRate.Numerator = 60U;
        swapChain.BufferDesc.RefreshRate.Denominator = 1U;
        swapChain.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
        swapChain.OutputWindow = w32Window;
        swapChain.SampleDesc.Count = SampleCount;
        swapChain.SampleDesc.Quality = SampleQuality;
        swapChain.Windowed = true;
    
        d3dResult = dxgiFactory->CreateSwapChain(D3DDevice, &swapChain, &SwapChain);
    }
    
    //Disable Alt + Enter and Print Screen shortcuts.
    dxgiFactory->MakeWindowAssociation(w32Window, DXGI_MWA_NO_PRINT_SCREEN | DXGI_MWA_NO_ALT_ENTER);
    
    dxgiFactory->Release();
    
    if (FAILED(d3dResult))
    {
        return false;
    }
    
    
    
    
    
    
    //Create render target view.
    
    ID3D11Texture2D* backBuffer = nullptr;
    d3dResult = SwapChain->GetBuffer(0U, __uuidof(ID3D11Texture2D), reinterpret_cast<void**>(&backBuffer));
    
    if (FAILED(d3dResult))
    {
        return false;
    }
    
    d3dResult = D3DDevice->CreateRenderTargetView(backBuffer, nullptr, &RenderTargetView);
    
    backBuffer->Release();
    
    if (FAILED(d3dResult))
    {
        return false;
    }
    
    
    //Create depth stencil texture.
    
    ID3D11Texture2D* DepthStencilTexture = nullptr;
    
    D3D11_TEXTURE2D_DESC depthTextureLayout;
    ZeroMemory(&depthTextureLayout, sizeof(depthTextureLayout));
    depthTextureLayout.Width = width;
    depthTextureLayout.Height = height;
    depthTextureLayout.MipLevels = 1U;
    depthTextureLayout.ArraySize = 1U;
    depthTextureLayout.Usage = D3D11_USAGE_DEFAULT;
    depthTextureLayout.CPUAccessFlags = 0U;
    depthTextureLayout.MiscFlags = 0U;
    depthTextureLayout.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
    depthTextureLayout.SampleDesc.Count = SampleCount;
    depthTextureLayout.SampleDesc.Quality = SampleQuality;
    depthTextureLayout.BindFlags = D3D11_BIND_DEPTH_STENCIL;
    d3dResult = D3DDevice->CreateTexture2D(&depthTextureLayout, nullptr, &DepthStencilTexture);
    
    if (FAILED(d3dResult))
    {
        return false;
    }
    
    
    //Create depth stencil.
    D3D11_DEPTH_STENCIL_DESC depthStencilLayout;
    depthStencilLayout.DepthEnable = true;
    depthStencilLayout.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
    depthStencilLayout.DepthFunc = D3D11_COMPARISON_LESS;
    depthStencilLayout.StencilEnable = true;
    depthStencilLayout.StencilReadMask = 0xFF;
    depthStencilLayout.StencilWriteMask = 0xFF;
    depthStencilLayout.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
    depthStencilLayout.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR;
    depthStencilLayout.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
    depthStencilLayout.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
    depthStencilLayout.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
    depthStencilLayout.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR;
    depthStencilLayout.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
    depthStencilLayout.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
    ID3D11DepthStencilState* depthStencilState;
    D3DDevice->CreateDepthStencilState(&depthStencilLayout, &depthStencilState);
    D3DDeviceContext->OMSetDepthStencilState(depthStencilState, 1U);
    
    
    
    //Create depth stencil view.
    
    D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewLayout;
    ZeroMemory(&depthStencilViewLayout, sizeof(depthStencilViewLayout));
    depthStencilViewLayout.Format = depthTextureLayout.Format;
    depthStencilViewLayout.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMS;
    depthStencilViewLayout.Texture2D.MipSlice = 0U;
    d3dResult = D3DDevice->CreateDepthStencilView(DepthStencilTexture, &depthStencilViewLayout, &DepthStencilView);
    
    DepthStencilTexture->Release();
    
    if (FAILED(d3dResult))
    {
        return false;
    }
    
    
    //Set output-merger render targets.
    D3DDeviceContext->OMSetRenderTargets(1U, &RenderTargetView, DepthStencilView);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-02-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多