Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
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.
- Depth-Stencil erőforrás- létrehozása
- Depth-Stencil-állapot létrehozása
- Depth-Stencil adatok összekapcsolása az OM szakaszhoz
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.
- Kompozitálás
- Dekálozás
- vázlatok és sziluettek
- Two-Sided rajzsablon
- Depth-Stencil puffer textúraként való olvasása
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.
Kapcsolódó témakörök