Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Pelajari cara menggunakan multisampling di aplikasi Universal Windows Platform (UWP) yang dibuat dengan Direct3D. Multisampling, juga dikenal sebagai antialiasing multi-sampel, adalah teknik grafis yang digunakan untuk mengurangi tampilan tepi alias. Ini bekerja dengan menghasilkan lebih banyak piksel daripada yang sebenarnya ada dalam target render akhir, lalu merata-ratakan nilai untuk mempertahankan tampilan tepian "sebagian" dalam piksel tertentu. Untuk deskripsi terperinci tentang cara kerja multisampling sebenarnya di Direct3D, lihat Aturan Rasterisasi Anti-AliasIng Multisample.
Multisampling dan rantai pertukaran model balik
Aplikasi UWP yang menggunakan DirectX harus menggunakan rantai pertukaran model flip. Rantai pertukaran (flip model) tidak mendukung multisampling secara langsung, tetapi multisampling masih dapat diterapkan dengan cara yang berbeda dengan merender adegan ke target render multisampel, lalu memindahkan hasil render multisampel ke buffer belakang sebelum menyajikan. Artikel ini menjelaskan langkah-langkah yang diperlukan untuk menambahkan multisampling ke aplikasi UWP Anda.
Cara menggunakan multisampling
Tingkat fitur Direct3D menjamin dukungan untuk kemampuan jumlah sampel minimum tertentu, dan menjamin format buffer tertentu akan tersedia yang mendukung multisampling. Perangkat grafis sering mendukung berbagai format dan jumlah sampel yang lebih luas daripada minimum yang diperlukan. Dukungan multisampling dapat ditentukan saat run-time dengan memeriksa dukungan fitur untuk multisampling menggunakan format DXGI tertentu, lalu memeriksa berbagai jumlah sampel yang dapat Anda gunakan dengan setiap format yang didukung.
Panggil ID3D11Device::CheckFeatureSupport untuk mengetahui format DXGI apa saja yang dapat digunakan dengan multisampling. Berikan format target render yang dapat digunakan game Anda. Target render dan target penyelesaian harus menggunakan format yang sama, jadi periksa D3D11_FORMAT_SUPPORT_MULTISAMPLE_RENDERTARGET dan D3D11_FORMAT_SUPPORT_MULTISAMPLE_RESOLVE.
**Fitur tingkat 9: ** Meskipun perangkat tingkat fitur 9 menjamin dukungan untuk format target render multisampel, tidak ada jaminan dukungan untuk target pemecahan multisampel. Jadi pemeriksaan ini diperlukan sebelum mencoba menggunakan teknik multisampling yang dijelaskan dalam topik ini.
Kode berikut memeriksa dukungan multisampling untuk semua nilai 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); } }
Untuk setiap format yang didukung, periksa dukungan jumlah sampel dengan memanggil ID3D11Device::CheckMultisampleQualityLevels.
Kode berikut memeriksa dukungan ukuran sampel untuk format DXGI yang didukung:
// 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); } } }
Catatan Gunakan ID3D11Device2::CheckMultisampleQualityLevels1 sebagai gantinya jika Anda perlu memeriksa dukungan multisample untuk buffer sumber daya bertingkat.
Buat buffer dan tampilan target render dengan jumlah sampel yang diinginkan. Gunakan DXGI_FORMAT, lebar, dan tinggi yang sama dengan rantai pertukaran, tetapi tentukan jumlah sampel yang lebih besar dari 1 dan gunakan dimensi tekstur multisampel (D3D11_RTV_DIMENSION_TEXTURE2DMS misalnya). Jika perlu, Anda dapat membuat ulang rantai pertukaran dengan pengaturan baru yang optimal untuk multisampling.
Kode berikut membuat target render multisampel:
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 ) );
Buffer kedalaman harus memiliki lebar, tinggi, jumlah sampel, dan dimensi tekstur yang sama agar sesuai dengan target render multisampled.
Kode berikut membuat buffer kedalaman multi-sampel:
// 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 ) );
Sekarang adalah waktu yang tepat untuk membuat viewport, karena lebar dan tinggi viewport juga harus cocok dengan target render.
Kode berikut membuat viewport:
// 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);
Render setiap bingkai ke target render multisampled. Saat penyajian selesai, panggil ID3D11DeviceContext::ResolveSubresource sebelum menyajikan bingkai. Ini menginstruksikan Direct3D untuk melakukan operasi multisampling, menghitung nilai setiap piksel untuk ditampilkan dan menempatkan hasilnya di buffer belakang. Buffer belakang kemudian berisi gambar akhir yang telah di-anti-alias dan dapat ditampilkan.
Kode berikut menyelesaikan sub-sumber daya sebelum menyajikan bingkai:
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);