Condividi tramite


Trasformazione di proiezione (Direct3D 9)

Si può pensare alla trasformazione della proiezione come il controllo degli interni della fotocamera; è analogo alla scelta di una lente per la fotocamera. Questo è il più complicato dei tre tipi di trasformazione. Questa discussione sulla trasformazione della proiezione è organizzata negli argomenti seguenti.

La matrice di proiezione è in genere una proiezione di scala e prospettiva. La trasformazione della proiezione converte il frustum di visualizzazione in una forma cuboide. Poiché la fine vicina del frustum di visualizzazione è più piccola dell'estremità lontana, questo ha l'effetto di espandere oggetti vicini alla fotocamera; questo è il modo in cui la prospettiva viene applicata alla scena.

In il frustum di visualizzazione, la distanza tra la fotocamera e l'origine dello spazio di trasformazione di visualizzazione viene definita in modo arbitrario come D, quindi la matrice di proiezione è simile alla figura seguente.

illustrazione della matrice di proiezione

La matrice di visualizzazione converte la fotocamera nell'origine traducendo nella direzione z di - D. La matrice di traduzione è simile alla figura seguente.

illustrazione della matrice di traduzione

La moltiplicazione della matrice di traslazione per la matrice di proiezione (T*P) fornisce la matrice di proiezione composita, come illustrato nella figura seguente.

illustrazione della matrice di proiezione composita

La trasformazione prospettica converte un frustum di visualizzazione in un nuovo spazio di coordinate. Si noti che il frustum diventa cuboide e anche che l'origine si sposta dall'angolo superiore destro della scena al centro, come illustrato nel diagramma seguente.

diagramma di come la prospettiva trasforma il frustum di visualizzazione in un nuovo spazio di coordinate

Nella trasformazione prospettica, i limiti delle direzioni x e y sono -1 e 1. I limiti della direzione z sono 0 per il piano anteriore e 1 per il piano posteriore.

Questa matrice converte e ridimensiona gli oggetti in base a una distanza specificata dalla fotocamera al piano di ritaglio vicino, ma non considera il campo di visualizzazione (fov) e i valori z prodotti per gli oggetti a distanza possono essere quasi identici, rendendo difficili i confronti di profondità. La matrice seguente risolve questi problemi e regola i vertici in modo da tenere conto delle proporzioni del riquadro di visualizzazione, rendendola una scelta ottimale per la proiezione prospettica.

illustrazione di una matrice per la proiezione prospettica

In questa matrice, Zn è il valore z del piano di ritaglio vicino. Le variabili w, h e Q hanno i significati seguenti. Si noti che fovw e fovk rappresentano i campi orizzontali e verticali della visualizzazione, in radianti.

equazioni dei significati delle variabili

Per l'applicazione, l'uso di angoli di visualizzazione per definire i coefficienti di ridimensionamento x e y potrebbe non essere utile come usare le dimensioni orizzontali e verticali del riquadro di visualizzazione (nello spazio della fotocamera). Come funziona la matematica, le due equazioni seguenti per w e h usano le dimensioni del viewport e sono equivalenti alle equazioni precedenti.

equazioni dei significati delle variabili w e h

In queste formule, Zn rappresenta la posizione del piano di ritaglio vicino e le variabili Vw e Vh rappresentano la larghezza e l'altezza del riquadro di visualizzazione, nello spazio della fotocamera.

Per un'applicazione C++, queste due dimensioni corrispondono direttamente ai membri Width e Height della struttura D3DVIEWPORT9.

Qualunque formula si decida di usare, assicurarsi di impostare Zn su un valore il più grande possibile, perché i valori z estremamente vicini alla fotocamera non variano di molto. In questo modo, i confronti di profondità usano buffer z a 16 bit piuttosto complicati.

Come per le trasformazioni del mondo e della visualizzazione, chiamare il metodo IDirect3DDevice9::SetTransform per impostare la trasformazione di proiezione.

Configurazione di una matrice di proiezione

La seguente funzione di esempio ProjectionMatrix imposta i piani di ritaglio anteriore e posteriore, nonché il campo orizzontale e verticale degli angoli di visualizzazione. I campi della vista devono essere minori di pi radianti.

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

Dopo aver creato la matrice, impostarla con IDirect3DDevice9::SetTransform specificando D3DTS_PROJECTION.

La libreria di utilità D3DX fornisce le funzioni seguenti per configurare la matrice di proiezione.

  • D3DXMatrixPerspectiveLH
  • D3DXMatrixPerspectiveRH
  • D3DXMatrixPerspectiveFovLH
  • D3DXMatrixPerspectiveFovRH
  • D3DXMatrixPerspectiveOffCenterLH
  • D3DXMatrixPerspectiveOffCenterRH

Matrice di proiezione W-Friendly

Direct3D può usare il componente w di un vertice trasformato da matrici di mondo, visualizzazione e proiezione per eseguire calcoli basati sulla profondità in effetti di buffer di profondità o nebbia. I calcoli, ad esempio questi, richiedono che la matrice di proiezione normalizzi w per essere equivalente allo spazio globale z. In breve, se la matrice di proiezione include un coefficiente (3,4) che non è 1, è necessario ridimensionare tutti i coefficienti in base al coefficiente inverso del coefficiente (3,4) per creare una matrice corretta. Se non si specifica una matrice conforme, gli effetti nebbia e il buffer di profondità non vengono applicati correttamente.

La figura seguente mostra una matrice di proiezione non conforme e la stessa matrice ridimensionata in modo che venga abilitata la nebbia relativa agli occhi.

illustrazioni di una matrice di proiezione non conforme e di una matrice con nebbia relativa agli occhi

Nelle matrici precedenti si presuppone che tutte le variabili siano diverse da zero. Per altre informazioni sulla nebbia relativa agli occhi, vedere Eye-Relative vs. Profondità basata su Z. Per informazioni sul buffer di profondità basato su w, vedere Depth Buffers (Direct3D 9).

Direct3D usa la matrice di proiezione attualmente impostata nei calcoli di profondità basati su w. Di conseguenza, le applicazioni devono impostare una matrice di proiezione conforme per ricevere le funzionalità basate su w desiderate, anche se non usano Direct3D per le trasformazioni.

trasformazioni