Pergunta

Estou trabalhando em um problema de visão computacional que requer renderizar um modelo 3D usando uma câmera calibrada. Estou escrevendo uma função que quebra a matriz da câmera calibrada em uma matriz de ModelView e uma matriz de projeção, mas encontrei um fenômeno interessante no OpenGL que desafia a explicação (pelo menos por mim).

A breve descrição é que negar a matriz de projeção resulta em nada sendo renderizado (pelo menos na minha experiência). Eu esperaria que multiplicar a matriz de projeção por qualquer escalar não tivesse efeito, porque transforma coordenadas homogêneas, que não são afetadas pela escala.

Abaixo está o meu raciocínio por que acho que isso é inesperado; Talvez alguém possa apontar onde meu raciocínio é falho.

Imagine a seguinte matriz de projeção de perspectiva, que fornece resultados corretos:

    [ a b c 0 ]
P = [ 0 d e 0 ]
    [ 0 0 f g ]
    [ 0 0 h 0 ]

Multiplicar isso por coordenadas da câmera fornece coordenadas de clipes homogêneas:

[x_c]   [ a b c 0 ]   [X_e]
[y_c] = [ 0 d e 0 ] * [Y_e]
[z_c]   [ 0 0 f g ]   [Z_e]
[w_c]   [ 0 0 h 0 ]   [W_e]

Finalmente, para obter coordenadas de dispositivos normalizadas, dividimos x_c, y_c e z_c por w_c:

[x_n]   [x_c/w_c]
[y_n] = [y_c/w_c]
[z_n]   [z_c/w_c]

Agora, se negarmos P, as coordenadas de clipes resultantes devem ser negadas, mas como são coordenadas homogêneas, a multiplicação por qualquer escalar (por exemplo -1) não deve afetar as coordenadas de dispositivo normalizado resultante. No entanto, no OpenGL, negando p resulta em nada sendo renderizado. Eu posso multiplicar P por qualquer escalar não negativo e obter exatamente os mesmos resultados renderizados, mas assim que multiplico por um escalar negativo, nada se torna. O que está acontecendo aqui??

Obrigado!

Foi útil?

Solução

Bem, a essência é que o teste de recorte é feito através de:

-w_c < x_c < w_c
-w_c < y_c < w_c
-w_c < z_c < w_c

Multiplicar por um valor negativo quebra este teste.

Outras dicas

Acabei de encontrar este boato, que faz progredir em direção a uma resposta:

Do Red Book, Apêndice G:

Evite usar coordenadas negativas de vértices W e coordenadas de textura Q negativa. O OpenGL pode não prender essas coordenadas corretamente e pode cometer erros de interpolação quando as primitivas de sombreamento definidas por essas coordenadas.

Inverter a matriz de projeção resultará em coordenadas negativas de recorte W e, aparentemente, o OpenGL não gosta disso. Mas alguém pode explicar por que o OpenGL não lida com esse caso?

referência: http://glprogramming.com/red/appendixg.html

Razões pelas quais posso pensar:

  • Ao inverter a matriz de projeção, as coordenadas não estarão mais nos seus planos Znear e Zfar da vista frustum (necessariamente maior que 0).
  • Para criar coordenadas de janela, as coordenadas de dispositivo normalizadas são traduzidas/escalonadas pela viewport. Portanto, se você usou um escalar negativo para as coordenadas do clipe, as coordenadas de dispositivos normalizadas (agora invertidas) traduzem a viewport para coordenadas de janelas que estão ... fora da sua janela (à esquerda e abaixo, se você quiser)

Além disso, desde que você mencionou o uso de uma matriz de câmera e que você inverteu a matriz de projeção, tenho que perguntar ... a quais matrizes você está aplicando o que da matriz da câmera? Operar na matriz de projeção Salvar próximo/distante/fovy/aspecto causa todos os tipos de problemas no buffer de profundidade, incluindo qualquer coisa que use Z (teste de profundidade, abate de face, etc.).

A seção de perguntas frequentes do OpenGL em Transformações tem mais alguns detalhes.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top