Transformeringar (Direct3D 9)
Den del av Direct3D som driver geometrin genom den fasta funktionsgeometripipelinen är transformmotorn. Den letar upp modellen och visningsprogrammet i världen, projekthörn för visning på skärmen och klipper hörn till visningsporten. Transformmotorn utför också belysningsberäkningar för att fastställa diffusa och spektulära komponenter vid varje hörn.
Geometripipelinen tar hörn som indata. Transformeringsmotorn tillämpar världen, vyn och projektionen på hörnen, klipper resultatet och skickar allt till rastreringen.
I pipelinens huvud deklareras en modells hörn i förhållande till ett lokalt koordinatsystem. Det här är ett lokalt ursprung och en orientering. Den här orienteringen av koordinater kallas ofta för modellutrymme och enskilda koordinater kallas för modellkoordinater.
Den första fasen av geometripipelinen omvandlar en modells hörn från deras lokala koordinatsystem till ett koordinatsystem som används av alla objekt i en scen. Processen att omorientera hörnen kallas världsomformning. Den här nya orienteringen kallas ofta för världsrymd och varje hörn i världsrymden deklareras med hjälp av världskoordinater.
I nästa steg är hörnen som beskriver din 3D-värld inriktade på en kamera. Programmet väljer alltså en synvinkel för scenen, och koordinaterna för världsrymden flyttas och roteras runt kamerans vy och förvandlar världsutrymmet till kamerautrymme. Det här är visningstransformen.
Nästa steg är projektionstransformionen. I den här delen av pipelinen skalas objekt vanligtvis med förhållande till deras avstånd från visningsprogrammet för att ge illusionen av djup till en scen; nära objekt görs för att visas större än avlägsna objekt, och så vidare. För enkelhetens skull refererar den här dokumentationen till det utrymme där hörn finns efter projektionstransformationen som projektionsutrymme. Vissa grafikböcker kan referera till projektionsutrymme som homogent utrymme efter perspektiv. Inte alla projektion transformerar skala storleken på objekt i en scen. En projektion som denna kallas ibland en affin eller ortoggonisk projektion.
I den sista delen av pipelinen tas alla hörn som inte visas på skärmen bort, så att rastreringen inte tar tid att beräkna färger och skuggning för något som aldrig kommer att ses. Den här processen kallas urklipp. Efter urklipp skalas de återstående hörnen enligt viewport-parametrarna och konverteras till skärmkoordinater. De resulterande hörnen, som visas på skärmen när scenen rastreras, finns i skärmutrymmet.
Transformeringar används för att konvertera objektgeometri från ett koordinatutrymme till ett annat. Direct3D använder matriser för att utföra 3D-transformeringar. Det här avsnittet beskriver hur matriser skapar 3D-transformeringar, beskriver några vanliga användningsområden för transformeringar och beskriver hur du kan kombinera matriser för att skapa en enda matris som omfattar flera transformeringar.
- World Transform (Direct3D 9) – konvertera från modellutrymme till världsrymd
- View Transform (Direct3D 9) – konvertera från världsrymden för att visa utrymme
- Projection Transform (Direct3D 9) – konvertera från visningsutrymme till projektionsutrymme
Matristransformeringar
I program som fungerar med 3D-grafik kan du använda geometriska transformeringar för att göra följande:
- Ange platsen för ett objekt i förhållande till ett annat objekt.
- Rotera och ändra storlek på objekt.
- Ändra visningspositioner, riktningar och perspektiv.
Du kan transformera valfri punkt (x,y,z) till en annan punkt (x', y', z') med hjälp av en 4x4-matris, enligt följande ekvation.
Utför följande ekvationer på (x, y, z) och matrisen för att producera punkten (x', y', z').
De vanligaste transformerna är översättning, rotation och skalning. Du kan kombinera matriserna som ger dessa effekter till en enda matris för att beräkna flera transformeringar samtidigt. Du kan till exempel skapa en enda matris för att översätta och rotera en serie punkter.
Matriser skrivs i radkolumnsordning. En matris som jämnt skalar hörn längs varje axel, så kallad enhetlig skalning, representeras av följande matris med matematisk notation.
I C++deklarerar Direct3D matriser som en tvådimensionell matris med hjälp av D3DMATRIX struktur. I följande exempel visas hur du initierar en D3DMATRIX struktur för att fungera som en enhetlig skalningsmatris.
// In this example, s is a variable of type float.
D3DMATRIX scale = {
s, 0.0f, 0.0f, 0.0f,
0.0f, s, 0.0f, 0.0f,
0.0f, 0.0f, s, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f
};
Översätta
Följande ekvation översätter punkten (x, y, z) till en ny punkt (x', y', z').
Du kan skapa en översättningsmatris manuellt i C++. I följande exempel visas källkoden för en funktion som skapar en matris för att översätta hörn.
D3DXMATRIX Translate(const float dx, const float dy, const float dz) {
D3DXMATRIX ret;
D3DXMatrixIdentity(&ret);
ret(3, 0) = dx;
ret(3, 1) = dy;
ret(3, 2) = dz;
return ret;
} // End of Translate
För enkelhetens skull tillhandahåller D3DX-verktygsbiblioteket funktionen D3DXMatrixTranslation.
Skala
Följande ekvation skalar punkten (x, y, z) efter godtyckliga värden i x-, y- och z-riktningarna till en ny punkt (x', y', z').
Rotera
De transformeringar som beskrivs här gäller för vänsterhänta koordinatsystem och kan därför skilja sig från transformeringsmatriser som du har sett någon annanstans.
Följande ekvation roterar punkten (x, y, z) runt x-axeln och producerar en ny punkt (x', y', z').
Följande ekvation roterar punkten runt y-axeln.
Följande ekvation roterar punkten runt z-axeln.
I dessa exempelmatriser står den grekiska bokstaven theta för rotationsvinkeln, i radianer. Vinklar mäts medsols när du tittar längs rotationsaxeln mot ursprunget.
I ett C++-program använder du D3DXMatrixRotationX, D3DXMatrixRotationYoch D3DXMatrixRotationZ funktioner som tillhandahålls av D3DX-verktygsbiblioteket för att skapa rotationsmatriser. Följande är koden för funktionen D3DXMatrixRotationX.
D3DXMATRIX* WINAPI D3DXMatrixRotationX
( D3DXMATRIX *pOut, float angle )
{
#if DBG
if(!pOut)
return NULL;
#endif
float sin, cos;
sincosf(angle, &sin, &cos); // Determine sin and cos of angle
pOut->_11 = 1.0f; pOut->_12 = 0.0f; pOut->_13 = 0.0f; pOut->_14 = 0.0f;
pOut->_21 = 0.0f; pOut->_22 = cos; pOut->_23 = sin; pOut->_24 = 0.0f;
pOut->_31 = 0.0f; pOut->_32 = -sin; pOut->_33 = cos; pOut->_34 = 0.0f;
pOut->_41 = 0.0f; pOut->_42 = 0.0f; pOut->_43 = 0.0f; pOut->_44 = 1.0f;
return pOut;
}
Sammanfoga matriser
En fördel med att använda matriser är att du kan kombinera effekterna av två eller flera matriser genom att multiplicera dem. Det innebär att du inte behöver använda två matriser för att rotera en modell och sedan översätta den till någon plats. I stället multiplicerar du rotations- och översättningsmatriserna för att skapa en sammansatt matris som innehåller alla deras effekter. Den här processen, som kallas matrissammanfogning, kan skrivas med följande ekvation.
I den här ekvationen är C den sammansatta matris som skapas, och M₁ via Mn är de enskilda matriserna. I de flesta fall sammanfogas bara två eller tre matriser, men det finns ingen gräns.
Använd funktionen D3DXMatrixMultiply för att utföra matris multiplikation.
Den ordning i vilken matrisens multiplikation utförs är avgörande. Föregående formel återspeglar vänster-till-höger-regeln för matrissammanfogning. Det vill: de synliga effekterna av de matriser som du använder för att skapa en sammansatt matris sker i vänster-till-höger-ordning. En typisk världsmatris visas i följande exempel. Tänk dig att du skapar världsmatrisen för ett stereotypt flygande tefat. Du skulle förmodligen vilja snurra det flygande tefatet runt dess centrum - y-axeln i modellutrymmet - och översätta det till någon annan plats i din scen. För att åstadkomma den här effekten skapar du först en rotationsmatris och multiplicerar den sedan med en översättningsmatris, enligt följande ekvation.
I den här formeln är Ry en matris för rotation om y-axeln, och Tw är en översättning till någon position i världskoordinater.
Den ordning i vilken du multiplicerar matriserna är viktig eftersom matris multiplikation, till skillnad från att multiplicera två skalärvärden, inte är kommutativ. Att multiplicera matriserna i motsatt ordning har den visuella effekten att översätta det flygande tefatet till dess världsrymdsposition och sedan rotera det runt om i världen.
Oavsett vilken typ av matris du skapar, kom ihåg regeln från vänster till höger för att säkerställa att du uppnår de förväntade effekterna.
Relaterade ämnen