Megosztás a következőn keresztül:


A Depth-Stencil funkcióinak konfigurálása

Ez a szakasz a mélységi rajzsablon pufferének beállításának lépéseit, valamint a kimeneti összeolvadás fázisának mélységi rajzsablon-állapotát ismerteti.

Ha már tudja, hogyan használhatja a mélységi rajzsablon pufferét és a megfelelő mélységi rajzsablon-állapotot, tekintse meg speciális rajzsablon-technikákat.

Depth-Stencil-erőforrás létrehozása

Hozza létre a mélységi rajzsablon pufferét egy textúraerőforrás használatával.

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 );

Depth-Stencil állapot létrehozása

A mélységi rajzsablon állapota azt jelzi, hogy a kimeneti-összevonási fázis hogyan hajthatja végre a mélységi rajzsablon-teszt. A mélységi rajzsablon-teszt meghatározza, hogy meg kell-e rajzolni egy adott képpontot.

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);

A DepthEnable és a StencilEnable lehetővé teszi (és letiltja) a mélység és a rajzsablon tesztelését. A mélységi tesztelés letiltásához és a mélységi pufferbe való írás megakadályozásához állítsa a DepthEnable értékét FALSE-re. Állítsa a StencilEnable értékét FALSE értékre, hogy letiltsa a rajzsablon tesztelését és megakadályozza az írást a rajzsablon pufferbe (amikor a DepthEnable FALSE, és a StencilEnable TRUE, a mélységi teszt mindig átmegy a rajzsablon műveletben).

A DepthEnable csak a kimeneti összevonási fázisra van hatással – ez nem befolyásolja az értékek kivágását, mélységi torzítását vagy rögzítését, mielőtt az adatok egy képpontárnyékolóba kerülnek.

Az Depth-Stencil adatok kötése az OM-fázishoz

Állítsa be a mélységi-stencil állapotot.

// Bind depth stencil state
pDevice->OMSetDepthStencilState(pDSState, 1);

Kösse a mélységi és rajzolási sablon erőforrást egy nézet használatával.

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

A renderelési célnézetek tömbje átadható a ID3D11DeviceContext::OMSetRenderTargets, de mindegyikük egyetlen mélységi stencil nézethez fog tartozni. A Direct3D 11 renderelési céltömbje egy olyan funkció, amely lehetővé teszi, hogy az alkalmazás egyszerre több renderelési célra is rendereljen a primitív szinten. A renderelési céltömbök jobb teljesítményt nyújtanak annál, amikor a renderelési célokat többszöri hívással egyedileg állítjuk be az ID3D11DeviceContext::OMSetRenderTargets módszerrel, amelyet lényegében a Direct3D 9-ben alkalmaztak.

A renderelési céloknak mind azonos típusú erőforrásnak kell lenniük. Többpéldányos antialiasing használata esetén minden kötött renderelési célnak és mélységi puffernek azonos mintaszámúnak kell lennie.

Ha egy puffert renderelési célként használ, a mélységi rajzsablon tesztelése és több renderelési cél nem támogatott.

  • Egyszerre akár 8 megjelenítési cél is köthető.
  • Minden renderelési célnak minden dimenzióban azonos méretűnek kell lennie (szélesség és magasság, 3D-s és tömbméret *Tömbtípusok esetén pedig mélység).
  • Előfordulhat, hogy minden renderelési cél eltérő adatformátummal rendelkezik.
  • Az írási maszkok szabályozzák, hogy a rendszer milyen adatokat írjon a renderelési célnak. A kimeneti írási maszkok a renderelési célok és az összetevők szintjén szabályozzák, hogy milyen adatok kerülnek rögzítésre a renderelési cél(ok)ra.

Fejlett rajzsablon-technikák

A mélységi rajzsablon pufferének rajzsablon része használható renderelési effektusok, például kompozitálás, matricázás és kirajzolás létrehozásához.

Kompozíció

Az alkalmazás a rajzsablon pufferével 2D vagy 3D képeket képes 3D-s jelenetbe összetettíteni. A rajzsablon pufferében lévő maszk a renderelési célfelület egy részének elzárására szolgál. A tárolt 2D-s információk, például szöveg vagy bitképek ezután írhatók az elzárt területre. Alternatív megoldásként az alkalmazás további 3D primitíveket jeleníthet meg a renderelt célfelület rajzsablonmaszkolt régiójában. Akár egy teljes jelenetet is megjeleníthet.

A játékok gyakran több 3D-s jelenetet is összehoznak. A vezetési játékok például általában visszapillantó tükröt mutatnak. A tükör a vezető mögötti 3D jelenet képét tartalmazza. Ez lényegében egy második 3D jelenet, amely a sofőr előrenéző képével van összekomponálva.

Matricázás

A Direct3D-alkalmazások skálázással szabályozják, hogy egy adott primitív kép mely képpontjait rajzolja a renderelő célfelületre. Az alkalmazások a primitívek képeire alkalmaznak skálákat, hogy lehetővé tegyék a koplanáris sokszögek helyes megjelenítését.

Ha például gumijeleket és sárga vonalakat alkalmaz egy úttestre, a jelöléseknek közvetlenül az út tetején kell megjelennie. A jelölések és az út z értékei azonban megegyeznek. Ezért előfordulhat, hogy a mélységi puffer nem hoz létre tiszta elkülönítést a kettő között. Egyes képpontok a hátsó primitíven lehetnek a tetejére renderelve az első primitívnek, és fordítva is igaz. Az eredményül kapott kép keretről keretre csillan. Ezt a jelenséget z-harcként vagy villódzásként nevezzük.

A probléma megoldásához használjon rajzsablont a hátsó alap elem azon szakaszának maszkolásához, ahol a dekoráció megjelenik. Kapcsolja ki a z-pufferelést, majd renderelje az első primitív képét a render-célfelület maszkolt területére.

A probléma megoldásához több textúra keverése is használható.

Vázlatok és sziluettek

A rajzsablonpuffert absztraktabb effektusokhoz használhatja, például a körvonalazást és a sziluettezést.

Ha az alkalmazás két renderelési áthaladást végez – az egyiket a rajzsablon maszkjának létrehozásához, a másodikat pedig a rajzsablon maszkjának a képre való alkalmazásához, de a primitívek valamivel kisebbek a második lépésnél – az eredményül kapott kép csak a primitív körvonalát fogja tartalmazni. Az alkalmazás ezután kitöltheti a kép rajzsablon által maszkolt területét egy színnel, így az alakzat domború megjelenést kap.

Ha a rajzsablon maszk mérete és alakja megegyezik a renderelt primitível, az eredményül kapott kép tartalmaz egy lyukat, ahol a primitívnek lennie kell. Az alkalmazás ezután kitöltheti a lyukat fekete színnel, hogy létrehozhassa a primitív sziluettjét.

Two-Sided rajzsablon

Az árnyéktérfogatok az árnyékok rajzolására szolgálnak a sablonpufferrel. Az alkalmazás kiszámítja a takaró geometria által vetett árnyéktérfogatokat úgy, hogy meghatározza a sziluett éleit, és ezeket a fénytől elhúzva 3D térfogatok készletévé alakítja. Ezek a kötetek ezután kétszer jelennek meg a rajzsablon pufferében.

Az első renderelés előre irányuló sokszögeket rajzol, és növeli a rajzsablon pufferértékeit. A második render az árnyékkötet hátrafelé néző sokszögeit rajzolja meg, és csökkenti a stencil puffer értékeit. Általában az összes növelt és csökkentett érték kioltják egymást. A jelenetet azonban már normál geometriával renderelték, így egyes képpontok nem mentek át a z-buffer teszten, mivel az árnyékkötet renderelésre került. A rajzsablon pufferében maradt értékek az árnyékban lévő képpontoknak felelnek meg. Ezeket a stencil puffer tartalmakat maszkként használják, hogy egy nagy, mindent magában foglaló fekete quadot beilleszthessünk a jelenetbe. Mivel a rajzsablon puffere maszkként működik, az eredmény az árnyékban lévő képpontok sötétítése.

Ez azt jelenti, hogy az árnyékgeometriát fényforrásonként kétszer rajzolják meg, ami nyomást gyakorol a GPU csúcsteljesítményére. A kétoldalas rajzsablon funkció úgy lett kialakítva, hogy enyhítse ezt a helyzetet. Ebben a megközelítésben két stencilállapot-készlet van (alább megnevezve): az egyik az előlapi háromszögekhez, a másik pedig a hátoldali háromszögekhez. Így csak egyetlen áthaladás rajzolódik meg árnyékkötetenként, fényenként.

A kétoldalas rajzsablon implementálásának egy példája a ShadowVolume10 mintatalálható.

A Depth-Stencil puffer textúraként való olvasása

Az inaktív mélységi rajzsablon-puffereket az árnyékolók textúraként olvashatják. A mélységi rajzsablon pufferét textúraként beolvasó alkalmazás két lépésben jelenik meg, az első lépés a mélységi rajzsablon pufferbe ír, a második pedig a pufferből olvas be. Ez lehetővé teszi, hogy egy árnyékoló összehasonlítsa a pufferbe korábban írt mélységi vagy rajzsablon-értékeket a jelenleg renderelt képpont értékével. Az összehasonlítás eredménye olyan hatások létrehozására használható, mint az árnyékleképezés vagy a finom részecskék a részecskerendszerben.

Ha mélységi rajzsablon-puffert szeretne létrehozni, amely mélységi rajzsablon-erőforrásként és árnyékolóerőforrásként is használható, néhány módosítást kell végrehajtania a Depth-Stencil erőforrás létrehozása szakasz mintakódjában.

  • A mélységi rajzsablon erőforrásának típus nélküli formátummal kell rendelkeznie, például DXGI_FORMAT_R32_TYPELESS.

    descDepth.Format = DXGI_FORMAT_R32_TYPELESS;
    
  • A mélységi rajzsablon-erőforrásnak a D3D10_BIND_DEPTH_STENCIL és D3D10_BIND_SHADER_RESOURCE kötésjelzőket is használnia kell.

    descDepth.BindFlags = D3D10_BIND_DEPTH_STENCIL | D3D10_BIND_SHADER_RESOURCE;
    

Emellett létre kell hozni egy árnyékoló erőforrás-nézetet a mélységi pufferhez, egy D3D11_SHADER_RESOURCE_VIEW_DESC struktúra és a ID3D11Device::CreateShaderResourceViewhasználatával. Az árnyékoló erőforrásnézete olyan beírt formátumot használ, mint például a DXGI_FORMAT_R32_FLOAT, amely megegyezik a mélységi rajzsablon-erőforrás létrehozásakor megadott típus nélküli formátummal.

Az első renderelési fázisban a mélységi puffer az Kötés Depth-Stencil adatoknak az OM szakasz részében leírtak szerint van csatolva. Vegye figyelembe, hogy a D3D11_DEPTH_STENCIL_VIEW_DESChelyettesítendő formátum egy típusos formátumot használ, például a DXGI_FORMAT_D32_FLOAT. Az első renderelés után a mélységi puffer tartalmazza a jelenet mélységi értékeit.

A második renderelési passzus során az ID3D11DeviceContext::OMSetRenderTargets függvényt használják a mélységi-sablon nézet NULL vagy egy másik mélységi-sablon erőforrásra állításához, és az árnyékoló erőforrásnézetét az ID3D11EffectShaderResourceVariable::SetResourcehasználatával továbbítják az árnyékolónak. Ez lehetővé teszi, hogy az árnyékoló megkeresse az első renderelési lépésben kiszámított mélységi értékeket. Vegye figyelembe, hogy a mélységi értékek lekéréséhez transzformációt kell alkalmazni, ha az első renderelési jel nézőpontja eltér a második renderelési lépéstől. Ha például árnyékleképezési technikát használ, az első renderelési menet egy fényforrás szemszögéből lesz, míg a második renderelési lépés a megtekintő szemszögéből lesz.

Output-Merger szakasz

folyamatszakaszok (Direct3D 10)