7.6 Câmera LookAt
Câmera LookAt é o nome dado ao frame de câmera virtual construído a partir das seguintes informações:
- Um ponto que corresponde à posição da câmera no espaço do mundo;
- Um ponto que corresponde à posição aonde a câmera está olhando, também no espaço do mundo28.
- Um vetor utilizado para indicar a direção “para cima” da câmera. Geralmente esse vetor é a direção .
A figura 7.25 ilustra esses elementos, incluindo os vetores que formam a base ortonormal da câmera.

Figura 7.25: Frame da câmera, representado em relação ao mundo.
O sistema de coordenadas da câmera segue a regra da mão direita. Note que a câmera está olhando na direção no espaço do mundo, que corresponde à direção do eixo negativo da câmera.
Inicialmente, não temos a base ortonormal . Só temos as seguintes informações (ilustradas na figura 7.26):
- A posição da câmera, ;
- A posição para onde a câmera deve ser direcionada, ;
- O vetor , que vamos considerar como sendo o vetor .

Figura 7.26: Parâmetros de uma câmera LookAt.
Através dessas informações construiremos a base . Com a base e o ponto de referência () temos o frame completo para criar a matriz de visão . Como vimos anteriormente, a matriz de visão representa uma mudança de frame: do espaço do mundo para o espaço da câmera.
Construindo o vetor n
Para construir a base ortonormal, primeiro fazemos para obter o vetor que aponta na direção contrária da direção de visão. Esse vetor é então normalizado para obter (figura 7.27):

Figura 7.27: Construção do vetor n da câmera LookAt.
Note que está sendo representado em coordenadas do espaço do mundo. Em relação à câmera, torna-se o vetor , isto é, a direção do eixo positivo da câmera (direção para trás da câmera).
Construindo o vetor u
Agora que temos , o segundo passo é calcular o produto vetorial e normalizar o resultado. Com isso obtemos o vetor perpendicular ao plano formado por e (figura 7.28):

Figura 7.28: Construção do vetor u da câmera LookAt.
No frame da câmera, corresponde ao vetor , isto é, a direção do eixo da câmera (direção à direita).
Construindo o vetor v
Embora seja perpendicular a e a , ainda não temos uma base ortonormal pois não é necessariamente perpendicular a . Na figura 7.28, e formam um ângulo menor que .
Para obter um vetor que seja mutuamente ortogonal a e , basta calcularmos o produto vetorial . O resultado é (figura 7.29) que já está normalizado pois e também têm comprimento 1.

Figura 7.29: Construção do vetor v da câmera LookAt.
Note que, em relação à câmera, corresponde ao vetor , isto é, o eixo da câmera (direção para cima).
Os vetores formam a base ortonormal da câmera, representados em relação ao espaço do mundo.
Construindo a matriz de visão
Para a construção da matriz de mudança de frame, vamos relembrar primeiro a matriz de mudança de base.
A matriz com colunas formadas pelos vetores representa uma mudança da base para a base transformada. A transformação é uma composição de rotações (por exemplo, ), que tem o efeito de rodar a base original para a nova.
O que temos atualmente é a base . Esses vetores estão representados em relação ao espaço do mundo. Se estivessem representados em relação ao espaço da câmera, a base seria . Então, se construirmos a matriz de mudança de base,
tal matriz representa a mudança do espaço da câmera para o espaço do mundo. Não é bem o que queremos. Gostaríamos da matriz que faz a transformação inversa, isto é, que converte coordenadas do mundo para a câmera. Entretanto, vamos prosseguir com da forma como está. Ao final poderemos calcular a matriz inversa da transformação completa, para finalmente obter .
Com a matriz , a base no espaço da câmera é transformada por rotações para resultar na base representada no espaço do mundo. Isso é ilustrado na figura 7.30.

Figura 7.30: Rotação da base representada no espaço da câmera, para a base representada no espaço do mundo.
Além da base, um frame também precisa de um ponto de referência. Esse ponto de referência é o próprio , que representa a origem no espaço da câmera. é o deslocamento necessário para mover a origem do espaço da câmera para sua posição no espaço do mundo. Em outras palavras, temos uma transformação de translação que pode ser representada pela matriz
Fazendo a composição das transformações, temos
A figura 7.31 ilustra como a matriz de transformação converte coordenadas do espaço da câmera para o espaço do mundo, que é o equivalente a rodar a base para (matriz de rotação ), e então transladar a origem para (matriz de translação ).

Figura 7.31: Mudança do espaço da câmera para o espaço do mundo.
Para obter , basta calcularmos a inversa de . Lembre-se que a inversa de uma matriz de rotação é a sua transposta, e a inversa da translação por é a translação por . Portanto,
A biblioteca GLM possui a função glm::lookAt
, definida em cabeçalho glm/gtc/matrix_transform.hpp
:
const& eye, glm::vec3 const& center, glm::vec3 const& up);
glm::mat4 glm::lookAt(glm::vec3 const& eye, glm::dvec3 const& center, glm::dvec3 const& up); glm::dmat4 glm::lookAt(glm::dvec3
glm::lookAt
gera a matriz de uma câmera LookAt, dados os parâmetros (eye
), (center
) e (up
).
Internamente, a função chama glm::lookAtRH
para gerar o frame baseado na regra da mão direita. O conteúdo dessa função é dado a seguir:
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER mat<4, 4, T, Q> lookAtRH(vec<3, T, Q> const& eye, vec<3, T, Q> const& center, vec<3, T, Q> const& up)
{
vec<3, T, Q> const f(normalize(center - eye));
vec<3, T, Q> const s(normalize(cross(f, up)));
vec<3, T, Q> const u(cross(s, f));
mat<4, 4, T, Q> Result(1);
Result[0][0] = s.x;
Result[1][0] = s.y;
Result[2][0] = s.z;
Result[0][1] = u.x;
Result[1][1] = u.y;
Result[2][1] = u.z;
Result[0][2] =-f.x;
Result[1][2] =-f.y;
Result[2][2] =-f.z;
Result[3][0] =-dot(s, eye);
Result[3][1] =-dot(u, eye);
Result[3][2] = dot(f, eye);
return Result;
}
Na linha 4, f
(vetor “forward”) é equivalente ao nosso .
Na linha 5, s
(vetor “side”) é o nosso vetor , calculado como , que é o mesmo que , seguido de uma normalização.
Na linha 6, u
é o nosso vetor , calculado como , que é o mesmo que .
Nas linhas 9 a 21 é montada a matriz Result
, que é a matriz . Internamente, a GLM armazena as matrizes no formato column-major, o que significa que o primeiro índice é a coluna, e o segundo índice é a linha. Levando isso em consideração, observe que a matriz resultante é de fato:
O ponto “at” também é chamado de “center” ou “target.”↩︎