如何将附近的像素数据发送到Direct3D 11中的Pixel-Shader?

时间:2015-03-22 19:23:15

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

我一直在浏览这些教程(只允许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(aka。片段)着色器,由以下代码组成:

//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;
}

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

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

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

我考虑过传统的MSAA(多样本抗锯齿),但我无法在D3D 11中找到有关如何成功完成任何信息的信息,除了我需要使用" BitBlt& #34; (位块传输)模型交换链首先。 (参见DXGI_SAMPLE_DESC1和DXGI_SAMPLE_DESC;只有1的计数和0的质量(没有AA)将导致绘制的东西。)此外,我想知道如何执行上述内容以便在需要其他情况下进行一般性理解我项目的各个方面。关于如何在D3D 11中执行MSAA的答案也是受欢迎的。

请仅使用D3D 11和HLSL代码。

谢谢!

2 个答案:

答案 0 :(得分:1)

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

使用绑定标记ID3D11Texture2DD3D11_BIND_RENDER_TARGET

创建D3D11_BIND_SHADER_RESOURCE

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

- 将场景移至步骤2中创建的ID3D11RenderTargetView

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

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


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

答案 1 :(得分:0)

我再次回答我自己的问题(从未使用过FXAA ......)。我在这里提供我的答案,对那些跟随我的脚步的人表示友善。

事实证明我错过了MSAA的深度模板视图。您希望SampleCount为1U用于禁用的MSAA,2U用于2XMSAA,4U用于4XMSAA,8U用于8XMSAA等。(使用ID3D11Device::CheckMultisampleQualityLevels至"探测"用于可行的MSAA级别...)你很漂亮我们总是希望对已禁用的MSAA使用0U的质量级别,对启用的MSAA使用1U。

以下是我正在使用的MSAA代码(您应该可以填写其余代码)。请注意,我使用了DXGI_FORMAT_D24_UNORM_S8_UINT和D3D11_DSV_DIMENSION_TEXTURE2DMS,并且深度纹理和深度模板视图的格式值相同,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);