Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Tato část popisuje kroky pro nastavení vyrovnávací paměti hloubkového vzorníku a stavu hloubkového vzorníku pro fázi slučování výstupů.
- Vytvořte prostředek Depth-Stencil
- Vytvoření stavu Depth-Stencil
- Připojit data Depth-Stencil ke stadiu OM
Jakmile víte, jak použít vyrovnávací paměť hloubkového vzorníku a odpovídající stav vzorníku hloubky, přečtěte si pokročilé techniky vzorníku.
Vytvořte prostředek Depth-Stencil
Vytvořte vyrovnávací paměť vzorníku hloubky pomocí prostředku textury.
ID3D11Texture2D* pDepthStencil = NULL;
D3D11_TEXTURE2D_DESC descDepth;
descDepth.Width = backBufferSurfaceDesc.Width;
descDepth.Height = backBufferSurfaceDesc.Height;
descDepth.MipLevels = 1;
descDepth.ArraySize = 1;
descDepth.Format = pDeviceSettings->d3d11.AutoDepthStencilFormat;
descDepth.SampleDesc.Count = 1;
descDepth.SampleDesc.Quality = 0;
descDepth.Usage = D3D11_USAGE_DEFAULT;
descDepth.BindFlags = D3D11_BIND_DEPTH_STENCIL;
descDepth.CPUAccessFlags = 0;
descDepth.MiscFlags = 0;
hr = pd3dDevice->CreateTexture2D( &descDepth, NULL, &pDepthStencil );
Vytvoření stavu Depth-Stencil
Stav podrobného vzorníku informuje fázi fúzi výstupu, jak provést hloubkový test vzorníku. Test hloubkového vzorníku určuje, zda má být daný pixel nakreslen nebo ne.
D3D11_DEPTH_STENCIL_DESC dsDesc;
// Depth test parameters
dsDesc.DepthEnable = true;
dsDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
dsDesc.DepthFunc = D3D11_COMPARISON_LESS;
// Stencil test parameters
dsDesc.StencilEnable = true;
dsDesc.StencilReadMask = 0xFF;
dsDesc.StencilWriteMask = 0xFF;
// Stencil operations if pixel is front-facing
dsDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
dsDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR;
dsDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
dsDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
// Stencil operations if pixel is back-facing
dsDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
dsDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_DECR;
dsDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
dsDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
// Create depth stencil state
ID3D11DepthStencilState * pDSState;
pd3dDevice->CreateDepthStencilState(&dsDesc, &pDSState);
DepthEnable a StencilEnable umožňují (a zakazují) testování hloubky a šablon. Nastavte DepthEnable na FALSE, abyste zakázali hloubkové testování a zabránili zápisu do depth bufferu. Nastavením StencilEnable na FALSE zakážete testování stencilu a zabráníte zápisu do stencilového bufferu (pokud je DepthEnable FALSE a StencilEnable TRUE, hloubkový test v operaci stencilu vždy projde).
DepthEnable ovlivňuje pouze fázi sloučení výstupu - nemá vliv na oříznutí, hloubkový bias nebo omezování hodnot před vstupem dat do pixelového shaderu.
Připojte data Depth-Stencil k úrovni OM
Vytvořte vazbu stavu podrobného vzorníku.
// Bind depth stencil state
pDevice->OMSetDepthStencilState(pDSState, 1);
Vytvořte vazbu prostředku podrobného vzorníku pomocí zobrazení.
D3D11_DEPTH_STENCIL_VIEW_DESC descDSV;
descDSV.Format = DXGI_FORMAT_D32_FLOAT_S8X24_UINT;
descDSV.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
descDSV.Texture2D.MipSlice = 0;
// Create the depth stencil view
ID3D11DepthStencilView* pDSV;
hr = pd3dDevice->CreateDepthStencilView( pDepthStencil, // Depth stencil texture
&descDSV, // Depth stencil desc
&pDSV ); // [out] Depth stencil view
// Bind the depth stencil view
pd3dDeviceContext->OMSetRenderTargets( 1, // One rendertarget view
&pRTV, // Render target view, created earlier
pDSV ); // Depth stencil view for the render target
Pole zobrazení cíle vykreslování může být předáno do ID3D11DeviceContext::OMSetRenderTargets, ale všechna tato zobrazení cíle vykreslování budou odpovídat zobrazení s jednou hloubkou vzorníku. Cílové pole vykreslení v Direct3D 11 je funkce, která umožňuje aplikaci vykreslit na více vykreslovaných cílů současně na primitivní úrovni. Vykreslovací cílové pole nabízí vyšší výkon oproti individuálnímu nastavení cílů vykreslování s použitím více volání ID3D11DeviceContext::OMSetRenderTargets (v podstatě metoda použitá v Direct3D 9).
Všechny cíle vykreslování musí být stejného typu prostředku. Pokud se použije multisamplingový antialiasing, musí mít všechny vázané renderovací cíle a hloubkové vyrovnávací paměti stejné počty vzorků.
Pokud se vyrovnávací paměť používá jako cíl vykreslení, testování hloubkového vzorníku a více cílů vykreslení se nepodporuje.
- Současně lze připojit až 8 cílů vykreslení.
- Všechny cíle vykreslení musí mít stejnou velikost ve všech rozměrech (šířka a výška a hloubka pro 3D nebo velikost pole pro *typy polí).
- Každý cíl vykreslení může mít jiný formát dat.
- Řídicí masky zápisu určují, jaká data se zapisují do cílového zařízení vykreslení. Výstupní masky zápisu určí na úrovni jednotlivých cílových renderů a komponent, jaká data se zapíší do renderovacích cílů.
Pokročilé techniky šablon
Část hloubkové-vzorníkové vyrovnávací paměti se dá použít k vytváření efektů vykreslování, jako jsou kompozitování, aplikace dekálů a ohraničení.
- Kompozice
- Polepy
- osnovy a siluety
- Two-Sided Šablona
- Čtení vyrovnávací paměti jako textury Depth-Stencil
Skládání
Vaše aplikace může použít stencil buffer ke složení 2D nebo 3D obrázků na 3D scénu. Maska ve vzorníkové vyrovnávací paměti se používá k zakrytí oblasti cílové renderovací plochy. Uložené 2D informace, například text nebo rastrové obrázky, je pak možné zapsat do odlehlé oblasti. Případně může vaše aplikace vykreslit další 3D primitiva do oblasti maskované vzorníkem cílové plochy vykreslování. Může dokonce vykreslit celou scénu.
Hry často skládají více 3D scén dohromady. Například závodní hry obvykle zobrazují zpětné zrcátko. Zrcadlo obsahuje zobrazení 3D scény za řidičem. Jedná se v podstatě o druhou 3D scénu složenou s pohledem řidiče dopředu.
Aplikace nálepek
Aplikace Direct3D používají dekálování k řízení toho, které grafické pixely z konkrétního primitivního obrázku se vykreslují na cílový povrch pro vykreslování. Aplikace používají na obrázky primitiv dekaly, aby bylo možné správně vykreslit kosplanární mnohoúhelníky.
Například při použití značek pneumatik a žlutých čar na silnici by se značky měly zobrazovat přímo na silnici. Hodnoty z-ové dopravního značení a cesty jsou však stejné. Proto hloubkový buffer nemusí zajistit jasné oddělení mezi nimi. Některé pixely v zadní primitivě mohou být vykresleny nad přední primitivou a naopak. Výsledný obrázek se zobrazí tak, že se třpytí z rámečku na rámeček. Tento efekt se nazývá z-fighting nebo blikání.
Chcete-li tento problém vyřešit, použijte vzorník k maskování části zadního primitiva, kde se zobrazí dekal. Vypněte Z-buffering a vykreslete obraz předního prvku do zamaskované oblasti renderovací plochy cíle.
K vyřešení tohoto problému lze použít prolínání více textur.
Osnovy a siluety
Můžete použít stencil buffer pro abstraktnější efekty, jako je například obrys a silueta.
Pokud vaše aplikace provádí dvě fáze vykreslování – jednu pro vygenerování masky vzorníku a druhou pro její aplikaci na obrázek, kde jsou primitivy ve druhém průchodu mírně menší – výsledný obrázek bude obsahovat pouze obrys primitiv. Aplikace pak může vyplnit šablonou maskovanou oblast obrázku plnou barvou, čímž je primitivní prvek opatřen embosovaným vzhledem.
Pokud má maska vzorníku stejnou velikost a tvar jako primitivum, které vykreslujete, výsledný obrázek obsahuje díru v místě, kde by mělo být primitivum. Vaše aplikace pak může vyplnit díru černou barvou a vytvořit siluetu objektu.
šablona Two-Sided
Stínové svazky se používají pro zobrazení stínů s šablonovým bufferem. Aplikace vypočítá stínové objemy vrhané zakrývající geometrií tím, že určí hrany siluety a vytlačí je směrem od světla do sady 3D objemů. Tyto svazky se pak vykreslí dvakrát do vyrovnávací paměti vzorníku.
První vykreslení nakreslí mnohoúhelníky směřující dopředu a zvýší hodnoty bufferu šablony. Druhé vykreslení vykresluje zpětné mnohoúhelníky stínového objemu a dekrementuje hodnoty stencil bufferu. Za normálních okolností se všechny inkrementované a dekrementované hodnoty navzájem ruší. Scéna však již byla vykreslena s normální geometrií, což vedlo k tomu, že některé pixely neprošly testem z-bufferu, když se vykresloval stínový svazek. Hodnoty, které zůstávají ve stencil bufferu, odpovídají pixelům, které jsou ve stínu. Tento zbývající obsah vyrovnávací paměti vzorníku se používá jako maska, pro alfa míchání velkého, všezahrnujícího černého čtyřúhelníku do scény. Se stencil bufferem jako maskou je výsledkem ztmavení pixelů, které jsou ve stínech.
To znamená, že geometrie stínu je nakreslena dvakrát pro každý zdroj světla, a proto klade tlak na propustnost vrcholů GPU. Funkce oboustranné šablony byla navržena tak, aby tuto situaci zmírnila. V tomto přístupu jsou dvě sady stavů šablony (pojmenované níže), jedna sada pro trojúhelníky směřující dopředu a druhá pro trojúhelníky směřující dozadu. Tímto způsobem je vykreslen pouze jeden průchod pro každý objem stínu a každé světlo.
Příklad dvoustranné implementace stencil najdete v ukázce ShadowVolume10.
Čtení textury z vyrovnávací paměti Depth-Stencil
Neaktivní hloubkový stencil buffer může být shaderem čten jako textura. Aplikace, která čte vyrovnávací paměť hloubkového vzorníku jako texturu, vykresluje ve dvou průchodech: první průchod zapisuje do vyrovnávací paměti hloubkového vzorníku a druhý průchod z ní čte. Díky tomu může shader porovnávat hodnoty hloubky nebo vzorníku, které byly dříve zapsány do vyrovnávací paměti, s hodnotou aktuálně vykresleného pixelu. Výsledek porovnání lze použít k vytvoření efektů, jako je mapování stínu nebo měkké částice v systému částic.
Pokud chcete vytvořit vyrovnávací paměť hloubky, kterou lze použít jako prostředek hloubky a shaderu, je potřeba provést několik změn v ukázkovém kódu v části Vytvoření Depth-Stencil Prostředku.
Prostředek podrobného vzorníku musí mít beztypový formát, například DXGI_FORMAT_R32_TYPELESS.
descDepth.Format = DXGI_FORMAT_R32_TYPELESS;Hloubkový-stencilový prostředek musí používat jak příznak vazby D3D10_BIND_DEPTH_STENCIL, tak D3D10_BIND_SHADER_RESOURCE.
descDepth.BindFlags = D3D10_BIND_DEPTH_STENCIL | D3D10_BIND_SHADER_RESOURCE;
Kromě toho je nutné vytvořit zobrazení shaderových prostředků pro hloubkový buffer pomocí struktury D3D11_SHADER_RESOURCE_VIEW_DESC a ID3D11Device::CreateShaderResourceView. Zobrazení prostředků shaderu bude používat typový formát, například DXGI_FORMAT_R32_FLOAT , který je ekvivalentní formátu bez typů zadaným při vytvoření prostředku podrobného vzorníku.
Při prvním vykreslovacím průchodu je hloubkový buffer vázán, jak je popsáno v sekci Bind Depth-Stencil Data to the OM Stage. Všimněte si, že formát předaný na D3D11_DEPTH_STENCIL_VIEW_DESC bude používat typový formát, jako je například DXGI_FORMAT_D32_FLOAT. Po prvním průchodu vykreslením bude v hloubkovém bufferu uložena hloubka hodnot scény.
Ve druhém vykreslení předejte ID3D11DeviceContext::OMSetRenderTargets funkce se používá k nastavení zobrazení podrobného vzorníku na NULL nebo jiný prostředek hloubkového vzorníku a zobrazení prostředků shaderu se předává shaderu pomocí ID3D11EffectShaderResourceVariable::SetResource. Shader tak může vyhledat hodnoty hloubky vypočítané v prvním vykreslovacím průchodu. Upozorňujeme, že k načtení hloubkových hodnot bude třeba použít transformaci, pokud se pohled na první průchod vykreslení liší od pohledu na druhý průchod vykreslení. Pokud se například používá technika mapování stínů, bude první průchod vykreslení z pohledu zdroje světla, zatímco druhý průchod vykreslení bude z perspektivy diváka.
Související témata
-
fáze kanálu (Direct3D 10)