Многосамплинг в приложениях универсальная платформа Windows (UWP)
Узнайте, как использовать многосамплинг в приложениях универсальная платформа Windows (UWP), созданных с помощью Direct3D. Мультисамплинг, также известный как многофакторная защита, — это графический метод, используемый для уменьшения внешнего вида псевдонимированных ребер. Он работает путем рисования большего количества пикселей, чем фактически в конечном целевом объекте отрисовки, а затем усреднения значений для поддержания внешнего вида "частичного" края в определенных пикселях. Подробное описание того, как мультисамплинг фактически работает в Direct3D, см. в разделе "Правила многофакторной защиты от псевдонима".
Многосамплинг и цепочка буферов модели переверки
Приложения UWP, использующие DirectX, должны использовать цепочки буферов модели переверки. Переключение цепочек буферов модели не поддерживает многосамплинирование напрямую, но многосамплинг по-прежнему можно применить другим способом, отрисовав сцену в многофакторное представление целевого представления отрисовки, а затем разрешив многофакторную целевую отрисовку в буфер обратно перед представлением. В этой статье описываются действия, необходимые для добавления многосамплинга в приложение UWP.
Использование многосамплинга
Уровни функций Direct3D гарантируют поддержку конкретных, минимальных возможностей подсчета выборок и гарантируют, что некоторые форматы буферов будут доступны, поддерживающие многофакторную настройку. Графические устройства часто поддерживают более широкий диапазон форматов и выборок, чем минимальный обязательный. Поддержка многофакторной поддержки можно определить во время выполнения, проверив поддержку функций для нескольких форматов DXGI, а затем проверив количество примеров, которые можно использовать с каждым поддерживаемым форматом.
Вызов ID3D11Device::CheckFeatureSupport , чтобы узнать, какие форматы DXGI можно использовать с многосамплингом. Укажите целевые форматы отрисовки, которые может использовать ваша игра. Целевой объект отрисовки и целевой объект разрешения должны использовать один и тот же формат, поэтому проверьте наличие D3D11_FORMAT_SUPPORT_MULTISAMPLE_RENDERTARGET и D3D11_FORMAT_SUPPORT_MULTISAMPLE_RESOLVE.
**Уровень компонентов 9. ** Хотя устройства уровня компонентов 9 гарантируют поддержку многофакторных форматов целевых форматов отрисовки, поддержка не гарантируется для целевых объектов для многосамплексного разрешения. Поэтому эта проверка необходима, прежде чем пытаться использовать многофакторную методику, описанную в этом разделе.
В следующем коде проверяется поддержка многосамплинга для всех значений 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); } }
Для каждого поддерживаемого формата запрос на поддержку количества примеров путем вызова ID3D11Device::CheckMultisampleQualityLevels.
Следующий код проверяет поддержку размера примера для поддерживаемых форматов DXGI:
// 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); } } }
Примечание. Используйте ID3D11Device2::CheckMultisampleQualityLevels1, если необходимо проверить поддержку многофакторных буферов ресурсов.
Создайте буфер и представление целевого объекта отрисовки с требуемым числом выборок. Используйте ту же DXGI_FORMAT, ширину и высоту, что и цепочка буферов, но укажите выборку, превышающую 1, и используйте многофакторное измерение текстуры (например, D3D11_RTV_DIMENSION_TEXTURE2DMS ). При необходимости можно повторно создать цепочку буферов с новыми параметрами, оптимальными для мультисамплинга.
Следующий код создает многофакторную целевую отрисовку:
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 ) );
Буфер глубины должен иметь ту же ширину, высоту, количество выборок и измерение текстуры, чтобы соответствовать целевому объекту многофакторной отрисовки.
Следующий код создает многофакторный буфер глубины:
// 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 ) );
Теперь рекомендуется создать окно просмотра, так как ширина окна просмотра и высота должны соответствовать целевому объекту отрисовки.
Следующий код создает окно просмотра:
// 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);
Отрисовка каждого кадра в многофакторную целевую отрисовку. После завершения отрисовки вызовите id3D11DeviceContext::ResolveSubresource перед представлением кадра. Это указывает Direct3D провести многофакторную операцию, вычислив значение каждого пикселя для отображения и размещения результата в обратном буфере. Затем буфер задней части содержит окончательный анти псевдоним изображения и может быть представлен.
Следующий код разрешает подресурс перед представлением кадра:
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);