Projektion transformering (Direct3D 9)
Du kan se projektionstransformeringen som att styra kamerans inre; det är analogt att välja en lins för kameran. Det här är den mest komplicerade av de tre transformeringstyperna. Den här diskussionen om projektionstransformeringen är organiserad i följande avsnitt.
Projektionsmatrisen är vanligtvis en skalnings- och perspektivprojektion. Projektionstransformeringen omvandlar visningsfrustumet till en kubformad form. Eftersom den nära änden av visning frustum är mindre än den bortre änden, har detta effekten av expanderande objekt som är nära kameran; det är så perspektiv tillämpas på scenen.
I visningsfrustumetdefinieras avståndet mellan kameran och ursprunget för visningstransformeringsutrymmet godtyckligt som D, så projektionsmatrisen ser ut som följande bild.
Visningsmatrisen översätter kameran till ursprunget genom att översätta i z-riktningen med - D. Översättningsmatrisen liknar följande bild.
Om du multiplicerar översättningsmatrisen med projektionsmatrisen (T*P) får du den sammansatta projektionsmatrisen, som du ser i följande bild.
Perspektivtransformen konverterar en visningsfrustum till ett nytt koordinatutrymme. Observera att frustum blir cuboid och också att ursprunget flyttas från det övre högra hörnet av scenen till mitten, som visas i följande diagram.
I perspektivtransformering är gränserna för x- och y-riktningarna -1 och 1. Gränserna för z-riktningen är 0 för det främre planet och 1 för det bakre planet.
Den här matrisen översätter och skalar objekt baserat på ett angivet avstånd från kameran till det nära urklippsplanet, men den tar inte hänsyn till visningsfältet (fov), och de z-värden som den producerar för objekt i fjärran kan vara nästan identiska, vilket gör djupjämförelser svåra. Följande matris åtgärdar dessa problem och justerar hörn för att ta hänsyn till proportionerna i visningsporten, vilket gör det till ett bra val för perspektivprojektionen.
I den här matrisen är Zn z-värdet för det nära urklippsplanet. Variablerna w, h och Q har följande betydelser. Observera att fovw och fovk representerar vyportens vågräta och lodräta fält i radianer.
För ditt program är det kanske inte lika praktiskt att använda synfältsvinklar för att definiera koefficienterna x- och y-skalning som att använda visningsplatsens vågräta och lodräta dimensioner (i kamerautrymmet). När matematiken fungerar använder följande två ekvationer för w och h vyportens dimensioner och motsvarar de föregående ekvationerna.
I dessa formler representerar Zn positionen för det nära urklippsplanet, och V-w- och Vh-variablerna representerar bredden och höjden på visningsplatsen i kamerautrymmet.
För ett C++-program motsvarar dessa två dimensioner direkt medlemmarna Width and Height i D3DVIEWPORT9-strukturen.
Oavsett vilken formel du väljer att använda måste du ange Zn till ett så stort värde som möjligt, eftersom z-värden som är extremt nära kameran inte varierar mycket. Detta gör djupjämförelser med 16-bitars z-buffertar något komplicerade.
Precis som med världen och visa transformeringar anropar du metoden IDirect3DDevice9::SetTransform för att ange projektionstransformeringen.
Konfigurera en projektionsmatris
Följande ProjectionMatrix-exempelfunktion anger de främre och bakre urklippsplanen, samt det vågräta och lodräta fältet med vyvinklar. Fälten i vyn bör vara mindre än pi-radianer.
D3DXMATRIX
ProjectionMatrix(const float near_plane, // Distance to near clipping
// plane
const float far_plane, // Distance to far clipping
// plane
const float fov_horiz, // Horizontal field of view
// angle, in radians
const float fov_vert) // Vertical field of view
// angle, in radians
{
float h, w, Q;
w = (float)1/tan(fov_horiz*0.5); // 1/tan(x) == cot(x)
h = (float)1/tan(fov_vert*0.5); // 1/tan(x) == cot(x)
Q = far_plane/(far_plane - near_plane);
D3DXMATRIX ret;
ZeroMemory(&ret, sizeof(ret));
ret(0, 0) = w;
ret(1, 1) = h;
ret(2, 2) = Q;
ret(3, 2) = -Q*near_plane;
ret(2, 3) = 1;
return ret;
} // End of ProjectionMatrix
När du har skapat matrisen anger du den med IDirect3DDevice9::SetTransform anger D3DTS_PROJECTION.
D3DX-verktygsbiblioteket innehåller följande funktioner som hjälper dig att konfigurera projektionsmatrisen.
- D3DXMatrixPerspectiveLH
- D3DXMatrixPerspectiveRH
- D3DXMatrixPerspectiveFovLH
- D3DXMatrixPerspectiveFovRH
- D3DXMatrixPerspectiveOffCenterLH
- D3DXMatrixPerspectiveOffCenterRH
En W-vänlig projektionsmatris
Direct3D kan använda w-komponenten i ett hörn som har omvandlats av värld, vy och projektionmatriser för att utföra djupbaserade beräkningar i djupbuffert- eller dimeffekter. Beräkningar som dessa kräver att projektionsmatrisen normaliserar w så att den motsvarar world-space z. Om projektionsmatrisen innehåller en (3,4) koefficient som inte är 1 måste du skala alla koefficienter med invertering av (3,4) koefficienten för att göra en korrekt matris. Om du inte tillhandahåller en kompatibel matris tillämpas inte dimeffekter och djupbuffertning korrekt.
Följande bild visar en icke-kompatibel projektionsmatris och samma matris skalas så att ögonrelativ dimma aktiveras.
I föregående matriser antas alla variabler vara icke-zero. Mer information om ögonrelativ dimma finns i Eye-Relative jämfört med Z-baserat djup. Information om w-baserad djupbuffertning finns i Djupbuffertar (Direct3D 9).
Direct3D använder den för närvarande angivna projektionsmatrisen i sina w-baserade djupberäkningar. Därför måste program ange en kompatibel projektionsmatris för att ta emot önskade w-baserade funktioner, även om de inte använder Direct3D för transformeringar.
Relaterade ämnen