Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
In deze sectie worden de stappen beschreven voor het instellen van de dieptestencilbuffer en de dieptestencilstatus voor de output-samenvoegingsfase.
- Een Depth-Stencil-resource maken
- Depth-Stencil status maken
- Depth-Stencil gegevens koppelen aan de OM-laag
Zodra u weet hoe u de dieptestencilbuffer en de bijbehorende dieptestenciltoestand gebruikt, verwijzen wij u naar geavanceerde stenciltechnieken.
Een Depth-Stencil-resource maken
Maak de dieptestencilbuffer met behulp van een textuurresource.
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 status maken
De dieptestencilstatus vertelt de fase van de uitvoerfusie hoe u de dieptestenciltestuitvoert. De dieptestenciltest bepaalt of een bepaalde pixel al dan niet moet worden getekend.
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 en StencilEnable schakelen de diepte- en stenciltests in en uit. Stel DepthEnable in op FALSE om dieptetests uit te schakelen en schrijven naar de dieptebuffer te voorkomen. Stel StencilEnable in op FALSE om het testen van stencils uit te schakelen en schrijven naar de stencilbuffer te voorkomen (wanneer DepthEnable ONWAAR is en StencilEnable WAAR is, wordt de dieptetest altijd doorgegeven in de stencilbewerking).
DepthEnable is alleen van invloed op de fase van de uitvoerfusie. Het heeft geen invloed op het knippen, diepte-bias of het vastzetten van waarden voordat de gegevens worden ingevoerd in een pixel-shader.
Depth-Stencil gegevens binden aan de OM-fase
Koppel de diepte-stenciltoestand.
// Bind depth stencil state
pDevice->OMSetDepthStencilState(pDSState, 1);
Bind de dieptestencilresource met behulp van een weergave.
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
Een matrix van render-doelweergaven kan worden doorgegeven aan ID3D11DeviceContext::OMSetRenderTargets, maar al deze render-doelweergaven komen overeen met één dieptestencilweergave. De renderdoelmatrix in Direct3D 11 is een functie waarmee een toepassing op meerdere renderdoelen tegelijk op primitief niveau kan renderen. Doelmatrices renderen bieden verbeterde prestaties ten opzichte van het afzonderlijk instellen van renderdoelen met meerdere aanroepen naar ID3D11DeviceContext::OMSetRenderTargets (in wezen de methode die wordt gebruikt in Direct3D 9).
Renderdoelen moeten allemaal hetzelfde type resource zijn. Als multisample antialiasing wordt gebruikt, moeten alle afhankelijke renderdoelen en dieptebuffers dezelfde steekproefaantallen hebben.
Wanneer een buffer wordt gebruikt als een renderdoel, worden dieptestenciltests en meerdere renderdoelen niet ondersteund.
- Er kunnen maar liefst 8 renderdoelen tegelijk worden gebonden.
- Alle renderdoelen moeten dezelfde grootte hebben in alle dimensies (breedte en hoogte en diepte voor 3D of matrixgrootte voor *Matrixtypen).
- Elk renderdoel kan een andere gegevensindeling hebben.
- Schrijfmaskers bepalen welke gegevens naar een renderdoel worden geschreven. Instellingen voor schrijfmaskers op een per-renderdoel- en per-onderdeelniveau bepalen welke gegevens naar het of de renderdoelen worden geschreven.
Geavanceerde stenciltechnieken
Het stencilgedeelte van de diepte-stencilbuffer kan worden gebruikt voor het maken van renderingeffecten, zoals compositing, decalen en omtrekken.
- Compositing
- Stickeren
- contouren en silhouetten
- StencilTwo-Sided
- de Depth-Stencil buffer als een textuur lezen
Compositeren
Uw toepassing kan de stencilbuffer gebruiken voor samengestelde 2D- of 3D-afbeeldingen op een 3D-scène. Een masker in de stencilbuffer wordt gebruikt om een gebied van het renderingdoeloppervlak af te sluiten. Opgeslagen 2D-gegevens, zoals tekst of bitmaps, kunnen vervolgens naar het onderbroken gebied worden geschreven. Uw toepassing kan alternatief extra 3D-primitieven weergeven op het door de stencil gemaskeerde gebied van het renderingdoeloppervlak. Het kan zelfs een hele scène weergeven.
Games maken vaak meerdere 3D-scènes samen. Rijspellen geven bijvoorbeeld meestal een spiegel aan de achterzijde weer. De spiegel bevat de weergave van de 3D-scène achter de driver. Het is in feite een tweede 3D-scène die is samengesteld met het vooraanzicht van de bestuurder.
Schaalaanpassing
Direct3D-toepassingen gebruiken schaalaanpassing om te bepalen welke pixels van een bepaalde primitieve afbeelding worden getekend op het renderingdoeloppervlak. Toepassingen brengen decals aan op de afbeeldingen van primitieven om coplanaire veelhoeken correct weer te geven.
Wanneer u bijvoorbeeld bandenmarkeringen en gele lijnen toepast op een weg, moeten de markeringen direct boven op de weg worden weergegeven. De z-waarden van de markeringen en de weg zijn echter hetzelfde. Daarom kan de dieptebuffer geen schone scheiding tussen de twee produceren. Sommige pixels in het achterste element kunnen boven op het voorste element worden weergegeven en omgekeerd. De resulterende afbeelding lijkt van frame naar frame te shimmeren. Dit effect wordt z-fighting of flikkering genoemd.
Als u dit probleem wilt oplossen, gebruikt u een stencil om het deel van de achterzijde van de primitie te maskeren waar de decal zal verschijnen. Schakel z-buffering uit en render de afbeelding van het voorste object in het gemaskeerde gebied van het renderdoeloppervlak.
Meerdere textuurmixen kunnen worden gebruikt om dit probleem op te lossen.
Contouren en silhouetten
U kunt de stencilbuffer gebruiken voor abstractere effecten, zoals overzicht en silhouetting.
Als uw toepassing twee render passes uitvoert - één om het stencilmasker te genereren en een tweede om het stencilmasker op de afbeelding toe te passen, maar met de primitieve elementen iets kleiner in de tweede pas - zal de resulterende afbeelding alleen het omtrek van de primitieve elementen bevatten. De toepassing kan vervolgens het stencilgemaskeerde gebied van de afbeelding vullen met een effen kleur, waardoor het primitieve element een reliëf uitstraling krijgt.
Als het stencilmasker dezelfde grootte en vorm heeft als het primitief dat u weergeeft, bevat de resulterende afbeelding een gat waar het primitief zou moeten zijn. Uw toepassing kan het gat vervolgens vullen met zwart om een silhouet van de primitieve te produceren.
Stencil Two-Sided
Schaduwvolumes worden gebruikt voor het tekenen van schaduwen met de stencilbuffer. De toepassing berekent de schaduwvolumes die door afschermende geometrie worden gegoten, door de silhouetranden te berekenen en ze weg van het licht te extruderen in een reeks 3D-volumes. Deze volumes worden vervolgens twee keer weergegeven in de stencilbuffer.
De eerste render plaatst voorwaarts gerichte polygonen en verhoogt de waarden in de stencilbuffer. Bij de tweede rendering worden de achterwaarts gerichte veelhoeken van het schaduwvolume getekend en worden de waarden in de stencilbuffer verlaagd. Normaal gesproken annuleren alle incrementele en aflopende waarden elkaar. De scène is echter al weergegeven met normale geometrie, waardoor sommige pixels de z-buffertest mislukken omdat het schaduwvolume wordt weergegeven. Waarden die in de stencilbuffer zijn achtergebleven, komen overeen met pixels die zich in de schaduw bevinden. Deze resterende inhoud van een stencilbuffer wordt gebruikt als masker om een grote, allesomvattende zwarte quad in de scène te combineren. Met de stencilbuffer die als masker fungeert, is het resultaat om pixels die zich in de schaduwen bevinden, donkerder te maken.
Dit betekent dat de schaduwgeometrie twee keer per lichtbron wordt getekend, waardoor de druk op de hoekpuntdoorvoer van de GPU wordt gelegd. De tweezijdige stencilfunctie is ontworpen om deze situatie te verhelpen. Bij deze benadering zijn er twee sets stencil-status (hieronder genoemd), één set voor de voorwaarts gerichte driehoeken en de andere voor de achterwaarts gerichte driehoeken. Op deze manier wordt per schaduwvolume slechts één pas getekend, per licht.
Een voorbeeld van tweezijdige stencil-implementatie vindt u in het ShadowVolume10-voorbeeld.
De Depth-Stencil buffer als textuur lezen
Een inactieve diepte-stencilbuffer kan door een shader als een texture worden gelezen. Een toepassing die een dieptestencilbuffer leest als een texture, wordt in twee doorgangen weergegeven, waarbij de eerste doorgang naar de diepte-stencilbuffer schrijft en de tweede doorgang uit de buffer leest. Hierdoor kan een shader diepte- of stencilwaarden die eerder naar de buffer zijn geschreven, vergelijken met de waarde voor de pixel die momenteel wordt weergegeven. Het resultaat van de vergelijking kan worden gebruikt om effecten te creëren, zoals schaduwtoewijzing of zachte deeltjes in een deeltjessysteem.
Als u een diepte-stencilbuffer wilt maken die kan worden gebruikt als zowel een diepte-stencilresource als een shader-resource, moeten enkele wijzigingen worden aangebracht in voorbeeldcode in de sectie Een Depth-Stencil Resource maken .
De resource van het dieptestencil moet een typeloze indeling hebben, zoals DXGI_FORMAT_R32_TYPELESS.
descDepth.Format = DXGI_FORMAT_R32_TYPELESS;De dieptestencilresource moet de bindingsvlaggen D3D10_BIND_DEPTH_STENCIL en D3D10_BIND_SHADER_RESOURCE gebruiken.
descDepth.BindFlags = D3D10_BIND_DEPTH_STENCIL | D3D10_BIND_SHADER_RESOURCE;
Daarnaast moet een shader-resourceweergave worden gecreëerd voor de dieptebuffer met behulp van een D3D11_SHADER_RESOURCE_VIEW_DESC structuur en ID3D11Device::CreateShaderResourceView. De shader-resourceweergave gebruikt een getypte indeling, zoals DXGI_FORMAT_R32_FLOAT die overeenkomt met de typeloze indeling die is opgegeven bij het maken van de dieptestencilresource.
In de eerste render is de dieptebuffer gebonden, zoals beschreven in de sectie Bind Depth-Stencil Data naar de sectie OM-fase . Houd er rekening mee dat de indeling is doorgegeven aan D3D11_DEPTH_STENCIL_VIEW_DESC. Opmaak gebruikt een getypte indeling, zoals DXGI_FORMAT_D32_FLOAT. Na de eerste renderpass bevat de dieptebuffer de dieptewaarden voor de scène.
In de tweede render-pas wordt de functie ID3D11DeviceContext::OMSetRenderTargets gebruikt om de dieptestencilweergave in te stellen op NULL of een andere dieptestencilresource, en wordt de shader-resourceweergave doorgegeven aan de shader met behulp van ID3D11EffectShaderResourceVariable::SetResource. Hierdoor kan de shader de dieptewaarden opzoeken die zijn berekend in de eerste renderingspas. Houd er rekening mee dat een transformatie moet worden toegepast om dieptewaarden op te halen als het perspectief van de eerste renderpas verschilt van de tweede renderpas. Als er bijvoorbeeld een schaduwtoewijzingstechniek wordt gebruikt, wordt de eerste renderpas vanuit het perspectief van een lichtbron gebruikt, terwijl de tweede render-pas vanuit het perspectief van de kijker wordt weergegeven.
Verwante onderwerpen