Dela via


Användarklippsplan på funktionsnivå 9 maskinvara

Från och med Windows 8 stöder Microsoft High Level Shader Language (HLSL) en syntax som du kan använda med Microsoft Direct3D 11 API för att ange användarklippsplan på funktionsnivå 9_x och högre. Du kan använda den här clip-planes-syntaxen för att skriva en skuggning och sedan använda skuggningsobjektet med Direct3D 11-API:et för att köra på alla Direct3D-funktionsnivåer.

Bakgrund

Du kan komma åt användarklippsplan i Microsoft Direct3D 9 API via IDirect3DDevice9::SetClipPlane och IDirect3DDevice9::GetClipPlane metoder. I Microsoft Direct3D 10 och senare kan du komma åt användarklippsplan via SV_ClipDistance semantik. Men innan Windows 8 var SV_ClipDistance inte tillgängligt för funktionsnivå 9_x maskinvara i Direct3D 10- eller Direct3D 11-API:erna. Innan Windows 8 var det enda sättet att komma åt användarklippsplan med funktionsnivå 9_x maskinvara via Direct3D 9-API:et. Direct3D Windows Store-appar kan inte använda Direct3D 9-API:et. Här beskriver vi den syntax som du kan använda för att komma åt användarklippsplan via Direct3D 11-API:et på funktionsnivå 9_x och högre.

Appar använder klippplan för att definiera en uppsättning osynliga plan i 3D-världen som klipper (kastar bort) alla ritade primitiver. Windows ritar inte någon bildpunkt som är på den negativa sidan av några klippplan. Appar kan sedan använda Clip Planes för att återge plana reflektioner.

Syntax

Använd den här syntaxen för att deklarera Clip Planes som funktionsattribut i en funktionsdeklaration. Här använder vi till exempel syntaxen för ett hörnskuggfragment:

cbuffer ClipPlaneConstantBuffer 
{
       float4 clipPlane1;
       float4 clipPlane2;
};

[clipplanes(clipPlane1,clipPlane2)]
VertexShaderOutput main(VertexShaderInput input)
{
       // the rest of the vertex shader doesn't refer to the clip plane
 
       …
 
       return output;
}

Det här exemplet för ett hörnskuggfragment anger två klippplan. Den visar att du måste placera det nya urklippsplan attribut inom hakparenteser omedelbart före returvärdet för hörnskuggningen. Inom parenteser efter urklippsplan attribut anger du en lista med upp till 6 float4 konstanter som definierar planets koefficienter för varje aktivt klippplan. Exemplet visar också att du måste göra så att koefficienterna för varje plan finns i en konstant buffert.

Not

Det finns ingen tillgänglig syntax för att inaktivera ett klippplan dynamiskt. Du måste antingen kompilera om en i övrigt identisk skuggning utan urklippsplan attribut, eller så kan appen ange koefficienterna i din konstanta buffert till noll så att planet inte längre påverkar någon geometri.

 

Den här syntaxen är tillgänglig för valfritt 4.0- eller senare hörnskuggningsmål, vilket inkluderar vs_4_0_level_9_1 och vs_4_0_level_9_3.

Skapa klippplan i klipputrymme på funktionsnivå 9 och högre

Här visar vi hur du skapar klippplan i klipputrymme på funktionsnivå 9_x och högre.

Bakgrundsläsning

"Introduktion till 3D-spelprogrammering med DirectX 10" av Frank D. Luna förklarar grafikmatematikbakgrunden (kapitel 1, 2 och 3) du behöver och de olika utrymmen och rymdtransformeringar som sker i hörnskuggningen (avsnitt 5.6 och 5.8).

Funktionsnivåer för 10Level9

I Direct3D 10 och senare kan du klippa i alla utrymmen som är meningsfulla, ofta i världsrymden eller i visningsutrymmet. Men Direct3D 9 använder klipputrymme, vilket är pre-perspektiv dividera projektion utrymme. Vektorer finns i klipputrymmet när hörnskuggningen skickar dem till steg som följer i grafikpipeline.

När du skriver en Windows Store-app måste du använda funktionsnivåer på 10Level9 (funktionsnivå 9_x) så att appen kan köras på funktionsnivå 9_x och högre maskinvara. Eftersom din app har stöd för funktionsnivå 9_x och högre måste du också använda den gemensamma funktionen för att tillämpa Clip-plan i klipputrymmet.

När du kompilerar en hörnskuggning med vs_4_0_level_9_1 eller senare kan den hörnskuggningen använda clipplan attribut. Ett Direct3D 10- eller senare-objekt har en punktprodukt av det utgivna hörnet som innehåller var och en av float4 globala konstanter som anges i attributet. Direct3D 9-objektet har tillräckligt med metadata för att 10Level9-körningen ska utfärda lämpliga anrop till IDirect3DDevice9::SetClipPlane.

Matematik för klippplan

Ett klippplan definieras av en vektor med 4 komponenter. De tre första komponenterna definierar en x-, y-z-vektor som kommer från ursprunget i det utrymme vi vill klippa ut. Den här vektorn innebär ett plan som är vinkelrätt mot vektorn och som löper genom ursprunget. Windows behåller alla pixlar på vektorsidan av planet och klipper alla bildpunkter bakom planet. Komponenten forth w skjuter tillbaka planet och gör att Windows klipper mindre (ett negativt w gör att Windows klipper mer) längs vektorlinjen. Om x-, y-z-komponenterna utgör en enhetsvektor (normaliserad) skjuter w tillbaka planet w-enheterna.

Matematiken som grafikprocessorn utför för att fastställa urklipp är en enkel punktprodukt mellan hörnvektorn (x, y, z, 1) och urklippsplanets vektor. Den här matematiska åtgärden skapar en projektionslängd på klippplansvektorn. En negativ punktprodukt visar hörnet som ska vara på den klippta sidan av planet.

Urklipp i visningsutrymme

Här är vårt hörn i visningsutrymmet:

hörn i visningsutrymme

Här är vårt klippplan i visningsutrymmet:

klippplan i visningsutrymme

Här är punktprodukten av hörn och klippplan i visningsutrymmet:

ClipDistance = v · C = vCₓ +vyCy + vzCz + Cw

Den här matematiska åtgärden fungerar för ett Direct3D 10- eller senare-objekt men fungerar inte för ett Direct3D 9-objekt. För Direct3D 9 måste vi först ta oss igenom vår projektionstransformering till klipputrymme.

Projektionsmatris

En projektionsmatris transformerar ett hörn från visningsutrymmet (där ursprunget är visningsprogrammets öga, +x är till höger, +y är uppe och +z är rakt fram) till klipputrymmet. Projektionsmatrisen läser hörnen för maskinvaruurklipp och rastreringssteget. Här är en standardperspektivmatris (andra projektioner kräver olika matematik):

*r* förhållandet mellan fönstrets bredd/höjd *α* visningsvinkel *f* avstånd från visningsprogrammet till det avlägsna planet *n* avstånd från visningsprogrammet till det nära planet
! [projektionsmatris](bilder/projection-matrix.png)

Nästa matris är en förenklad version av den tidigare matrisen. Vi visar matrisen förenklad så att vi kan använda den senare i matrisens multiplikationsåtgärd.

förenklad projektionsmatris

Nu omvandlar vi vårt hörn för visningsutrymme till klipputrymme med en matris som multipliceras:

matris multiplicerar

I vår matris multiplikationsåtgärd justeras våra x- och y-komponenter bara något, men våra z- och w-komponenter är ganska manglade. Vårt klippplan ger oss inte det vi vill ha längre.

Clip Space Clip-plan

Här vill vi skapa ett clip space clip-plan vars punktprodukt med vårt hörn för klipputrymme ger oss samma värde som v · C i avsnittet Urklipp i visningsutrymmet.

klippplan

mot · C = mot P · CP

vCₓ +vyCy + vzCz + Cw = vPCPₓ +vyPyCPy + vzAyCPz + BCPz + vzCPw

Nu kan vi dela upp den föregående matematiska åtgärden med hörnkomponenten i fyra separata ekvationer:

x hörnkomponent i Clip Plane-produkten

y-hörnkomponenten i clip plane-produkten

w hörnkomponent i Clip Plane-produkten

z hörnkomponent i clip plane-produkt

Vårt rymdurklippsplan och vår projektionsmatris härleds och ger oss vårt klipputrymmesklippplan.

klipp ut urklippsplanet

programmeringsguide för HLSL-

syntax för funktionsdeklaration