Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
Saiba como usar a amostragem múltipla em aplicativos da Plataforma Universal do Windows (UWP) criados com Direct3D. Multiamostragem, também conhecida como suavização de várias amostras, é uma técnica gráfica usada para reduzir a aparência de bordas com alias. Ele funciona desenhando mais pixels do que realmente estão no destino de renderização final e, em seguida, calculando valores médios para manter a aparência de uma borda "parcial" em determinados pixels. Para obter uma descrição detalhada de como a amostragem múltipla realmente funciona no Direct3D, consulte Multisample Anti-Aliasing Rasterization Rules.
Multisampling e a cadeia de troca do modelo flip
Os aplicativos UWP que usam DirectX devem usar cadeias de permuta de modelo invertido. As cadeias de permuta de modelo de inversão não suportam multiamostragem diretamente, mas a multiamostragem ainda pode ser aplicada de uma maneira diferente, renderizando a cena em uma exibição de destino de renderização com várias amostras e, em seguida, resolvendo o destino de renderização com várias amostras para o buffer traseiro antes da apresentação. Este artigo explica as etapas necessárias para adicionar multiamostragem ao seu aplicativo UWP.
Como usar a amostragem múltipla
Os níveis de recursos do Direct3D garantem suporte para recursos específicos e mínimos de contagem de amostras e garantem que determinados formatos de buffer estejam disponíveis para suportar multiamostragem. Os dispositivos gráficos geralmente suportam uma gama mais ampla de formatos e contagens de amostras do que o mínimo necessário. O suporte a várias amostragens pode ser determinado em tempo de execução verificando o suporte de recursos para multiamostragem com formatos DXGI específicos e, em seguida, verificando as contagens de amostras que você pode usar com cada formato suportado.
Ligue ID3D11Device::CheckFeatureSupport para descobrir quais formatos DXGI podem ser usados com amostragem múltipla. Forneça os formatos de destino de renderização que seu jogo pode usar. Tanto o destino de renderização quanto o destino de resolução devem usar o mesmo formato, portanto, verifique ambos D3D11_FORMAT_SUPPORT_MULTISAMPLE_RENDERTARGET e D3D11_FORMAT_SUPPORT_MULTISAMPLE_RESOLVE.
**Nível de recurso 9: ** Embora os dispositivos de nível de recurso 9 garantam suporte para formatos de destino de renderização com várias amostras, o suporte não é garantido para alvos de resolução de multiamostragem. Portanto, esta verificação é necessária antes de tentar usar a técnica de amostragem múltipla descrita neste tópico.
O código a seguir verifica o suporte a várias amostragens para todos os valores de DXGI_FORMAT:
// Determine the format support for multisampling. for (UINT i = 1; i < DXGI_FORMAT_MAX; i++) { DXGI_FORMAT inFormat = safe_cast<DXGI_FORMAT>(i); UINT formatSupport = 0; HRESULT hr = m_d3dDevice->CheckFormatSupport(inFormat, &formatSupport); if ((formatSupport & D3D11_FORMAT_SUPPORT_MULTISAMPLE_RESOLVE) && (formatSupport & D3D11_FORMAT_SUPPORT_MULTISAMPLE_RENDERTARGET) ) { m_supportInfo->SetFormatSupport(i, true); } else { m_supportInfo->SetFormatSupport(i, false); } }Para cada formato suportado, consulte suporte à contagem de amostras chamando ID3D11Device::CheckMultisampleQualityLevels.
O código a seguir verifica o suporte ao tamanho da amostra para formatos DXGI suportados:
// Find available sample sizes for each supported format. for (unsigned int i = 0; i < DXGI_FORMAT_MAX; i++) { for (unsigned int j = 1; j < MAX_SAMPLES_CHECK; j++) { UINT numQualityFlags; HRESULT test = m_d3dDevice->CheckMultisampleQualityLevels( (DXGI_FORMAT) i, j, &numQualityFlags ); if (SUCCEEDED(test) && (numQualityFlags > 0)) { m_supportInfo->SetSampleSize(i, j, 1); m_supportInfo->SetQualityFlagsAt(i, j, numQualityFlags); } } }Observação Utilize ID3D11Device2::CheckMultisampleQualityLevels1 em vez disso, se precisar verificar o suporte a multisample para buffers de recursos em mosaico.
Crie um buffer e renderize a visualização de destino com a contagem de amostras desejada. Use a mesma DXGI_FORMAT, largura e altura que a cadeia de permuta, mas especifique uma contagem de amostras maior que 1 e use uma dimensão de textura com várias amostras (D3D11_RTV_DIMENSION_TEXTURE2DMS por exemplo). Se necessário, pode-se recriar a cadeia de troca com novas configurações que são ideais para multiamostragem.
O código a seguir cria um destino de renderização com várias amostras:
float widthMulti = m_d3dRenderTargetSize.Width; float heightMulti = m_d3dRenderTargetSize.Height; D3D11_TEXTURE2D_DESC offScreenSurfaceDesc; ZeroMemory(&offScreenSurfaceDesc, sizeof(D3D11_TEXTURE2D_DESC)); offScreenSurfaceDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; offScreenSurfaceDesc.Width = static_cast<UINT>(widthMulti); offScreenSurfaceDesc.Height = static_cast<UINT>(heightMulti); offScreenSurfaceDesc.BindFlags = D3D11_BIND_RENDER_TARGET; offScreenSurfaceDesc.MipLevels = 1; offScreenSurfaceDesc.ArraySize = 1; offScreenSurfaceDesc.SampleDesc.Count = m_sampleSize; offScreenSurfaceDesc.SampleDesc.Quality = m_qualityFlags; // Create a surface that's multisampled. DX::ThrowIfFailed( m_d3dDevice->CreateTexture2D( &offScreenSurfaceDesc, nullptr, &m_offScreenSurface) ); // Create a render target view. CD3D11_RENDER_TARGET_VIEW_DESC renderTargetViewDesc(D3D11_RTV_DIMENSION_TEXTURE2DMS); DX::ThrowIfFailed( m_d3dDevice->CreateRenderTargetView( m_offScreenSurface.Get(), &renderTargetViewDesc, &m_d3dRenderTargetView ) );O buffer de profundidade deve ter a mesma largura, altura, contagem de amostras e dimensão de textura para corresponder ao destino de renderização com várias amostras.
O código a seguir cria um buffer de profundidade com várias amostras:
// Create a depth stencil view for use with 3D rendering if needed. CD3D11_TEXTURE2D_DESC depthStencilDesc( DXGI_FORMAT_D24_UNORM_S8_UINT, static_cast<UINT>(widthMulti), static_cast<UINT>(heightMulti), 1, // This depth stencil view has only one texture. 1, // Use a single mipmap level. D3D11_BIND_DEPTH_STENCIL, D3D11_USAGE_DEFAULT, 0, m_sampleSize, m_qualityFlags ); ComPtr<ID3D11Texture2D> depthStencil; DX::ThrowIfFailed( m_d3dDevice->CreateTexture2D( &depthStencilDesc, nullptr, &depthStencil ) ); CD3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc(D3D11_DSV_DIMENSION_TEXTURE2DMS); DX::ThrowIfFailed( m_d3dDevice->CreateDepthStencilView( depthStencil.Get(), &depthStencilViewDesc, &m_d3dDepthStencilView ) );Agora é um bom momento para criar o visor, porque a largura e a altura do visor também devem corresponder ao destino de renderização.
O código a seguir cria uma janela de visualização:
// Set the 3D rendering viewport to target the entire window. m_screenViewport = CD3D11_VIEWPORT( 0.0f, 0.0f, widthMulti / m_scalingFactor, heightMulti / m_scalingFactor ); m_d3dContext->RSSetViewports(1, &m_screenViewport);Renderize cada quadro para o destino de renderização com várias amostras. Quando a renderização estiver concluída, chame ID3D11DeviceContext::ResolveSubresource antes de apresentar o quadro. Isso instrui o Direct3D a executar a operação de multiamostragem, calculando o valor de cada pixel para exibição e colocando o resultado no buffer traseiro. O back buffer então contém a imagem final com anti-aliasing e pode ser apresentada.
O código a seguir resolve o subrecurso antes de apresentar o quadro:
if (m_sampleSize > 1) { unsigned int sub = D3D11CalcSubresource(0, 0, 1); m_d3dContext->ResolveSubresource( m_backBuffer.Get(), sub, m_offScreenSurface.Get(), sub, DXGI_FORMAT_B8G8R8A8_UNORM ); } // The first argument instructs DXGI to block until VSync, putting the application // to sleep until the next VSync. This ensures that we don't waste any cycles rendering // frames that will never be displayed to the screen. hr = m_swapChain->Present(1, 0);