Partilhar via


Transformação de projeção (Direct3D 9)

Você pode pensar na transformação de projeção como controlar os internos da câmera; É análogo à escolha de uma lente para a câmera. Este é o mais complicado dos três tipos de transformação. Esta discussão sobre a transformação da projeção está organizada nos seguintes tópicos.

A matriz de projeção é tipicamente uma projeção em escala e perspetiva. A transformação de projeção converte o frustum de visualização em uma forma cuboide. Como a extremidade próxima do frustum de visualização é menor do que a extremidade distante, isso tem o efeito de expandir objetos que estão perto da câmera; É assim que a perspetiva é aplicada à cena.

Em o frustum de visualização, a distância entre a câmera e a origem do espaço de transformação de visualização é definida arbitrariamente como D, de modo que a matriz de projeção se parece com a ilustração a seguir.

ilustração da matriz de projeção

A matriz de visualização traduz a câmera para a origem, traduzindo na direção z por - D. A matriz de tradução é como a ilustração a seguir.

ilustração da matriz de tradução

Multiplicando a matriz de translação pela matriz de projeção (T*P) obtém-se a matriz de projeção composta, como mostra a ilustração a seguir.

ilustração da matriz de projeção composta

A transformação de perspetiva converte um frustum de visualização em um novo espaço de coordenadas. Observe que o frustum se torna cuboide e também que a origem se move do canto superior direito da cena para o centro, como mostrado no diagrama a seguir.

diagrama de como a perspetiva se transforma muda o frustum de visualização em um novo espaço de coordenadas

Na transformação de perspetiva, os limites das direções x e y são -1 e 1. Os limites da direção z são 0 para o plano dianteiro e 1 para o plano traseiro.

Essa matriz traduz e dimensiona objetos com base em uma distância especificada da câmera para o plano de recorte próximo, mas não considera o campo de visão (fov), e os valores z que ela produz para objetos à distância podem ser quase idênticos, dificultando as comparações de profundidade. A matriz a seguir aborda essas questões e ajusta vértices para levar em conta a proporção do visor, tornando-a uma boa escolha para a projeção de perspetiva.

ilustração de uma matriz para a projeção da perspetiva

Nesta matriz, Zn é o valor z do plano de corte próximo. As variáveis w, h e Q têm os seguintes significados. Note que fovw e fovk representam os campos de visão horizontais e verticais do visor, em radianos.

equações das variáveis significados

Para seu aplicativo, usar ângulos de campo de visão para definir os coeficientes de escala x e y pode não ser tão conveniente quanto usar as dimensões horizontais e verticais do visor (no espaço da câmera). À medida que a matemática funciona, as duas equações a seguir para w e h usam as dimensões do visor e são equivalentes às equações anteriores.

equações dos significados das variáveis w e h

Nestas fórmulas, Zn representa a posição do plano de recorte próximo e as variáveis Vw e Vh representam a largura e a altura do visor, no espaço da câmara.

Para um aplicativo C++, essas duas dimensões correspondem diretamente aos membros Width e Height da estrutura D3DVIEWPORT9.

Seja qual for a fórmula que você decidir usar, certifique-se de definir Zn para um valor o maior possível, porque os valores z extremamente próximos da câmera não variam muito. Isso torna as comparações de profundidade usando z-buffers de 16 bits um pouco complicadas.

Assim como acontece com as transformações de mundo e exibição, você chama o IDirect3DDevice9::SetTransform método para definir a transformação de projeção.

Configurando uma matriz de projeção

A função de exemplo ProjectionMatrix a seguir define os planos de recorte frontal e traseiro, bem como os ângulos de campo de visão horizontal e vertical. Os campos de visão devem ser inferiores a pi radianos.

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

Depois de criar a matriz, defina-a com IDirect3DDevice9::SetTransform especificando D3DTS_PROJECTION.

A biblioteca de utilitários D3DX fornece as seguintes funções para ajudá-lo a configurar sua matriz de projeção.

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

Uma matriz de projeção W-Friendly

O Direct3D pode usar o componente w de um vértice que foi transformado pelas matrizes de mundo, visão e projeção para executar cálculos baseados em profundidade em efeitos de buffer de profundidade ou névoa. Cálculos como esses exigem que sua matriz de projeção normalize w para ser equivalente ao espaço-mundo z. Em suma, se a sua matriz de projeção incluir um coeficiente (3,4) que não seja 1, você deve escalar todos os coeficientes pelo inverso do coeficiente (3,4) para fazer uma matriz adequada. Se você não fornecer uma matriz compatível, os efeitos de névoa e o buffer de profundidade não serão aplicados corretamente.

A ilustração a seguir mostra uma matriz de projeção não compatível e a mesma matriz dimensionada para que a névoa relativa aos olhos seja ativada.

ilustrações de uma matriz de projeção não compatível e uma matriz com névoa relativa aos olhos

Nas matrizes anteriores, todas as variáveis são assumidas como diferentes de zero. Para obter mais informações sobre névoa relativa aos olhos, consulte de profundidade baseada emEye-Relative vs. Z . Para obter informações sobre buffer de profundidade baseado em w, consulte Depth Buffers (Direct3D 9).

O Direct3D usa a matriz de projeção atualmente definida em seus cálculos de profundidade baseados em w. Como resultado, os aplicativos devem definir uma matriz de projeção compatível para receber os recursos baseados em w desejados, mesmo que não usem Direct3D para transformações.

transforma