Trasformazione di proiezione (Direct3D 9)

Si può pensare alla trasformazione di proiezione come controllare gli interni della fotocamera; è analogo alla scelta di un obiettivo 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 di proiezione converte il frustum di visualizzazione in una forma cuboide. Poiché la fine vicina del frustum di visualizzazione è più piccola rispetto all'estremità lontana, questo ha l'effetto di espandere gli oggetti che si trovano vicino alla fotocamera; questo è il modo in cui la prospettiva viene applicata alla scena.

Nel frustum di visualizzazione, la distanza tra la fotocamera e l'origine dello spazio di trasformazione di visualizzazione viene definita arbitrariamente 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 traslazione è simile alla figura seguente.

illustrazione della matrice di traslazione

Moltiplicando la matrice di traslazione per la matrice di proiezione (T*P) viene fornita 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 del modo in cui la trasformazione prospettica modifica 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 nella 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 riquadro di visualizzazione 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 tu decida di usare, assicurati di impostare Zn su un valore il più grande possibile, perché i valori z estremamente vicini alla fotocamera non variano 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, si chiama il metodo IDirect3DDevice9::SetTransform per impostare la trasformazione di proiezione.

Configurazione di una matrice di proiezione

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

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.

Matrice di proiezione W-Friendly

Direct3D può usare il componente w di un vertice trasformato dalle 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) diverso da 1, è necessario ridimensionare tutti i coefficienti inversa 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. Z-Based Depth.For more information about eye-relative fog, see Eye-Relative vs. Z-Based Depth. Per informazioni sul buffer di profondità basato su w, vedere Depth Buffers (Direct3D 9).For information about w-based depth buffering, see 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