Compartilhar via


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

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

A matriz de projeção normalmente é uma projeção de escala e perspectiva. A transformação de projeção converte o frusto de exibição em uma forma cuboide. Como o final próximo do frusto de exibição é menor do que a extremidade distante, isso tem o efeito de expandir objetos que estão próximos à câmera; é assim que a perspectiva é aplicada à cena.

Em o frusto de exibição, a distância entre a câmera e a origem do espaço de transformação de exibiçã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 exibição converte 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

Multiplicar a matriz de tradução pela matriz de projeção (T*P) fornece a matriz de projeção composta, conforme mostrado na ilustração a seguir.

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

A transformação de perspectiva converte um frusto de exibiçã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, conforme mostrado no diagrama a seguir.

diagrama de como a transformação de perspectiva altera o frusto de exibição em um novo espaço de coordenadas

Na transformação de perspectiva, 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 frontal e 1 para o plano traseiro.

Essa matriz converte 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 exibição (fov) e os valores z que produz para objetos à distância podem ser quase idênticos, dificultando comparações de profundidade. A matriz a seguir aborda esses problemas e ajusta os vértices para considerar a taxa de proporção do visor, tornando-a uma boa opção para a projeção de perspectiva.

ilustração de uma matriz para a projeção de perspectiva

Nesta matriz, Zn é o valor z do plano de recorte próximo. As variáveis w, h e Q têm os seguintes significados. Observe que fovw e fovk representam os campos de exibição horizontal e vertical do visor, em radianos.

equações dos significados da variável

Para seu aplicativo, usar ângulos de campo de exibiçã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). Conforme 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 da variável w e h

Nessas 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âmera.

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, defina zn como um valor tão grande quanto possível, pois os valores z extremamente próximos à câmera não variam muito. Isso torna as comparações de profundidade usando buffers z de 16 bits um pouco complicadas.

Assim como acontece com o mundo e as transformações de exibição, você chama o método IDirect3DDevice9::SetTransform 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 o campo horizontal e vertical dos ângulos de exibição. Os campos de exibição devem ser menores que radianos 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

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 amigável para W

O Direct3D pode usar o w-component de um vértice que foi transformado pelo mundo, visualização e matrizes de projeção para executar cálculos baseados em profundidade em efeitos de buffer de profundidade ou neblina. Cálculos como esses exigem que sua matriz de projeção normalize w para ser equivalente ao espaço mundial z. Em suma, se a matriz de projeção incluir um coeficiente (3,4) que não seja 1, você deverá dimensionar todos os coeficientes pelo inverso do coeficiente (3,4) para criar uma matriz adequada. Se você não fornecer uma matriz compatível, os efeitos de neblina 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 neblina relativa aos olhos seja habilitada.

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

Nas matrizes anteriores, todas as variáveis são consideradas não zero. Para obter mais informações sobre a neblina relativa aos olhos, consulte Eye-Relative vs. Z-Based Depth. Para obter informações sobre o buffer de profundidade baseado em w, consulte buffers de profundidade(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 em conformidade para receber os recursos desejados baseados em w, mesmo que não usem o Direct3D para transformações.

transformações de