Blending-functionaliteit configureren
Voor elke pixel-shader-uitvoer (RGBA-waarde) worden mengbewerkingen uitgevoerd voordat de uitkomst in een renderdoel wordt geschreven. Als multisampling is ingeschakeld, wordt blending uitgevoerd op elke multisample; anders wordt blending op elke pixel uitgevoerd.
De blendstatus maken
De blendstatus is een verzameling statussen die worden gebruikt om het mengen te regelen. Deze statussen (gedefinieerd in D3D11_BLEND_DESC1) worden gebruikt om het blend-statusobject te maken door ID3D11Device1::CreateBlendState1aan te roepen.
Hier is bijvoorbeeld een heel eenvoudig voorbeeld van het maken van blend-state waarmee alfamenging wordt uitgeschakeld en geen pixelmaskering per onderdeel wordt gebruikt.
ID3D11BlendState1* g_pBlendStateNoBlend = NULL;
D3D11_BLEND_DESC1 BlendState;
ZeroMemory(&BlendState, sizeof(D3D11_BLEND_DESC1));
BlendState.RenderTarget[0].BlendEnable = FALSE;
BlendState.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
pd3dDevice->CreateBlendState1(&BlendState, &g_pBlendStateNoBlend);
Dit voorbeeld is vergelijkbaar met de HLSLWithoutFX10 Sample.
De blendstatus binden
Nadat u het blend-state-object hebt gemaakt, bindt u het object blend-state aan de fase van de uitvoerfusie door ID3D11DeviceContext::OMSetBlendStateaan te roepen.
float blendFactor[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
UINT sampleMask = 0xffffffff;
pd3dDevice->OMSetBlendState(g_pBlendStateNoBlend, blendFactor, sampleMask);
Deze API heeft drie parameters: het blend-state-object, een blend-factor met vier onderdelen en een voorbeeldmasker. U kunt NULL doorgeven voor het blend-state-object om de standaard blend-state op te geven of een blend-state-object doorgeven. Als u het blend-state-object hebt gemaakt met D3D11_BLEND_BLEND_FACTOR of D3D11_BLEND_INV_BLEND_FACTOR, kunt u een blend-factor doorgeven om waarden voor zowel de pixel-shader als het renderdoel te moduleren. Als u het blend-state-object niet hebt gemaakt met D3D11_BLEND_BLEND_FACTOR of D3D11_BLEND_INV_BLEND_FACTOR, kunt u nog steeds een niet-NULL-blendfactor doorgeven, maar de blendingfase gebruikt de blendfactor niet; de runtime slaat de blend-factor op en u kunt later ID3D11DeviceContext::OMGetBlendState aanroepen om de blend-factor op te halen. Als u NULL-doorgeeft, gebruikt of slaat de runtime een blend-factor op die gelijk is aan { 1, 1, 1, 1 }. Het voorbeeldmasker is een door de gebruiker gedefinieerd masker dat bepaalt hoe u het bestaande renderdoel kunt samplen voordat u het bijwerkt. Het standaardmonstermasker is 0xffffffff dat puntsampling aangeeft.
In de meeste dieptebufferschema's is de pixel die het dichtst bij de camera ligt degene die wordt getekend. Wanneer de status van het dieptestencil instelt, kan het DepthFunc- lid van D3D11_DEPTH_STENCIL_DESC elke D3D11_COMPARISON_FUNCzijn. Normaal gesproken wilt u DepthFuncD3D11_COMPARISON_LESS, zodat de pixels die het dichtst bij de camera liggen, de pixels achter hen overschrijven. Afhankelijk van de behoeften van uw toepassing, kunnen echter alle andere vergelijkingsfuncties worden gebruikt om de dieptetest uit te voeren.
Geavanceerde blending-onderwerpen
Alfa-To-Coverage
Alfa-naar-dekking is een multisampling-techniek die vooral nuttig is in situaties zoals dichte begroeiing, waar meerdere overlappende veelhoeken alfatransparantie gebruiken om randen binnen het oppervlak te definiëren.
U kunt de AlphaToCoverageEnable lid van D3D11_BLEND_DESC1 of D3D11_BLEND_DESC gebruiken om te schakelen of de runtime het .a-onderdeel (alfa) van het uitvoerregister converteert SV_Target0 van de pixel-shader naar een dekkingsmasker met n stappen (gegeven een n-voorbeeld RenderTarget-). De runtime voert een AND bewerking uit van dit masker met de typische sampledekking voor de pixel in het primitief (naast het samplemasker) om te bepalen welke samples moeten worden bijgewerkt in alle actieve RenderTarget's.
Als de pixelshader SV_Coverageuitvoert, schakelt de runtime alpha-to-coverage uit.
Notitie
In multisampling deelt de runtime slechts één dekking voor alle RenderTarget-s. Het feit dat de runtime .a van uitvoer SV_Target0 leest en naar dekkingsgraad converteert wanneer AlphaToCoverageEnable WAAR is, verandert de waarde van .a die naar de blender gaat op RenderTarget 0 niet (als er daar een RenderTarget- is ingesteld). Als u alfa-naar-dekking inschakelt, heeft dit over het algemeen geen invloed op hoe alle kleuruitvoeren van pixel-shaders interageren met RenderTarget-'s door de uitvoerfusie fase, behalve dat de runtime een EN bewerking van het dekkingsmasker uitvoert met het alfa-to-dekkingsmasker. Alfa-naar-dekking werkt onafhankelijk van het feit of de runtime RenderTarget- kan combineren of of u blending gebruikt op RenderTarget-.
Grafische hardware specificeert niet precies hoe het pixel-shader SV_Target0.a (alfa) converteert naar een dekkingsmasker, behalve dat een alfa van 0 (of minder) moet worden toegewezen aan geen dekking, en een alfa van 1 (of hoger) moet worden toegewezen aan volledige dekking (voordat de runtime een EN bewerking met de werkelijke primitieve dekking uitvoert). Naarmate alfa van 0 tot 1 gaat, moet de resulterende dekking over het algemeen monotonisch toenemen. Hardware kan echter gebiedshering uitvoeren om een betere kwantisatie van alfawaarden te bieden ten koste van ruimtelijke resolutie en ruis. Een alfawaarde van NaN (Geen getal) resulteert in een masker zonder dekking (nul).
Alfa-to-dekking wordt ook traditioneel gebruikt voor schermdoorzichtigheid of het definiëren van gedetailleerde silhouetten voor anderszins ondoorzichtige sprites.
Pixel shader-uitvoer combineren
Met deze functie kan de uitvoersamenvoeging zowel de pixel-shader-uitvoer tegelijkertijd gebruiken als invoerbron voor een mengbewerking met de enkele renderdoel in sleuf 0.
In dit voorbeeld worden twee resultaten gebruikt en gecombineerd in één keer, waarbij één in de bestemming wordt vervlochten met een vermenigvuldiging en de andere wordt bij opgeteld:
SrcBlend = D3D11_BLEND_ONE;
DestBlend = D3D11_BLEND_SRC1_COLOR;
In dit voorbeeld wordt de uitvoer van de eerste pixel shader geconfigureerd als de bronkleur en de tweede uitvoer als een blend-factor per kleuronderdeel.
SrcBlend = D3D11_BLEND_SRC1_COLOR;
DestBlend = D3D11_BLEND_INV_SRC1_COLOR;
In dit voorbeeld wordt geïllustreerd hoe de blend-factoren moeten overeenkomen met de shader swizzles.
SrcFactor = D3D11_BLEND_SRC1_ALPHA;
DestFactor = D3D11_BLEND_SRC_COLOR;
OutputWriteMask[0] = .ra; // pseudocode for setting the mask at
// RenderTarget slot 0 to .ra
Samen impliceren de blend-factoren en de shader-code dat de pixel-shader vereist is om ten minste o0.r en o1.a uit te voeren. Extra uitvoeronderdelen kunnen door de shader worden uitgevoerd, maar worden genegeerd, minder onderdelen produceren niet-gedefinieerde resultaten.
Verwante onderwerpen