Por que movemos o mundo em vez da câmera?

87

Ouvi dizer que, em um jogo OpenGL, o que fazemos para deixar o jogador se mover não é mover a câmera, mas mover o mundo inteiro.

Por exemplo, aqui está um extrato deste tutorial: Matriz do OpenGL View

Na vida real, você está acostumado a mover a câmera para alterar a visualização de uma determinada cena, no OpenGL é o contrário. A câmera no OpenGL não pode se mover e está definida para estar localizada em (0,0,0) voltada para a direção Z negativa. Isso significa que, em vez de mover e girar a câmera, o mundo é movido e girado em torno da câmera para construir a visão apropriada.

Por que nós fazemos isso?

danijar
fonte
1
Uma câmera representa apenas uma visão de projeção. Então você transforma o mundo para obter a projeção que deseja. O conceito é estranho, mas ele realmente faz sentido ... de uma maneira ... Eu acho
Sidar
@ Sharethis, melhorei minha resposta com uma explicação melhor. Adicionado perspectiva de projeção com matemática e opção de câmera 3D (câmera virtual). Pode ser útil para você e outras pessoas.
Md Mahbubur Rahman
4
Na verdade, isso não é verdade, já que as duas operações (mover a câmera ou os objetos do mundo) são simétricas, não há como saber qual operação ocorreu. Você está pensando no mundo se movendo em torno da câmera, mas igualmente outra pessoa pode visualizar a câmera se movendo em sentido inverso em relação ao mundo ... Ok, para que você possa mover objetos em relação um ao outro, para que uma maneira seja mais intuitiva, mas nenhuma pessoa está "errada", ambas as formas de visualizar a situação são boas em situações diferentes. Muitas vezes, é útil pensar em ambos.
user3728501

Respostas:

72

Por quê ?

Porque, uma câmera representa uma visão de projeção.

Mas no caso da câmera 3D (câmera virtual), a câmera se move ao invés do mundo. Fiz uma explicação detalhada depois desta resposta.

Compreendendo matematicamente

A vista de projeção se move pelo espaço e muda sua orientação. A primeira coisa a notar é que a projeção desejada na tela não muda com a direção da vista.

Por esse motivo, transformamos outras coisas para obter a projeção desejada.

Compreendendo http://opengl.org

Para dar a aparência de mover a câmera, seu aplicativo OpenGL deve mover a cena com o inverso da transformação da câmera. No que diz respeito ao OpenGL, não há câmera. Mais especificamente, a câmera está sempre localizada na coordenada do espaço ocular (0, 0, 0)

Compreendendo http://open.gl

Também deseja compartilhar as seguintes linhas da parte da matriz View de http://open.gl/transformations

Para simular uma transformação de câmera, você realmente precisa transformar o mundo com o inverso dessa transformação. Exemplo: se você quiser mover a câmera para cima, precisará mover o mundo para baixo.

Compreensão por perspectiva

No mundo real, vemos as coisas de uma maneira que é chamada de "perspectiva".

Perspectiva refere-se ao conceito de que objetos mais distantes parecem menores do que aqueles que estão mais próximos de você. Perspectiva também significa que se você estiver sentado no meio de uma estrada reta, na verdade verá as bordas da estrada como duas linhas convergentes.

Essa é a perspectiva. A perspectiva é crítica em projetos 3D. Sem perspectiva, o mundo 3D não parece real.

Embora isso possa parecer natural e óbvio, é importante considerar que, ao criar uma renderização 3D em um computador, você está tentando simular um mundo 3D na tela do computador, que é uma superfície 2D.

Imagine que atrás da tela do computador existe uma espécie de cena 3D real, e você a está assistindo através do "vidro" da tela do computador. Usando a perspectiva, seu objetivo é criar código que renderize o que é "projetado" nesse "vidro" da tela como se houvesse esse mundo 3D real atrás da tela. A única ressalva é que este mundo 3D não é real ... é apenas uma simulação matemática de um mundo 3D.

Portanto, ao usar a renderização 3D para simular uma cena em 3D e projetar a cena 3D na superfície 2D da tela, o processo é chamado de projeção em perspectiva.

Comece imaginando intuitivamente o que você deseja alcançar. Se um objeto estiver mais próximo do visualizador, ele deverá parecer maior. Se o objeto estiver mais distante, ele deverá parecer menor. Além disso, se um objeto estiver se afastando do visualizador, em linha reta, você deseja que ele converja para o centro da tela, à medida que se afasta um pouco mais.

Traduzindo perspectiva em matemática

Como você vê a ilustração na figura a seguir, imagine que um objeto está posicionado em sua cena 3D. No mundo 3D, a posição do objeto pode ser descrita como xW, yW, zW, referindo-se a um sistema de coordenadas 3D com a origem no ponto de vista. É aí que o objeto está realmente posicionado, na cena 3D além da tela.

insira a descrição da imagem aqui

À medida que o visualizador observa esse objeto na tela, o objeto 3D é "projetado" para uma posição 2D descrita como xP e yP, que faz referência ao sistema de coordenadas 2D da tela (plano de projeção).

Para colocar esses valores em uma fórmula matemática, usarei um sistema de coordenadas 3D para coordenadas mundiais, em que o eixo x aponta para a direita, y aponta para cima e pontos z positivos na tela. A origem 3D refere-se à localização do olho do espectador. Então, o vidro da tela está em um plano ortogonal (em ângulo reto) ao eixo z, em algum z que eu chamarei de zProj.

Você pode calcular as posições projetadas xP e yP, dividindo as posições mundiais xW e yW, por zW, da seguinte maneira:

xP = K1 * xW / zW
yP = K2 * yW / zW

K1 e K2 são constantes derivadas de fatores geométricos, como a proporção do seu plano de projeção (sua janela de visualização) e o "campo de visão" do seu olho, que leva em consideração o grau de visão de grande angular.

Você pode ver como essa transformação simula a perspectiva. Os pontos próximos aos lados da tela são empurrados em direção ao centro à medida que a distância do olho (zW) aumenta. Ao mesmo tempo, os pontos mais próximos do centro (0,0) são muito menos afetados pela distância do olho e permanecem próximos do centro.

Essa divisão por z é a famosa "divisão da perspectiva".

Agora, considere que um objeto na cena 3D é definido como uma série de vértices. Portanto, aplicando esse tipo de transformação a todos os vértices da geometria, você efetivamente garante que o objeto encolherá quando estiver mais distante do ponto do olho.

Outros casos importantes

  • No caso da câmera 3D (câmera virtual), a câmera se move ao invés do mundo.

Para entender melhor as câmeras 3D, imagine que você está gravando um filme. Você precisa configurar uma cena que deseja gravar e precisa de uma câmera. Para obter as imagens, você percorrerá a cena com sua câmera, fotografando os objetos na cena de diferentes ângulos e pontos de vista.

O mesmo processo de filmagem ocorre com uma câmera 3D. Você precisa de uma câmera "virtual", que possa percorrer a cena "virtual" que você criou.

Dois estilos populares de fotografia envolvem observar o mundo através dos olhos de um personagem (também conhecido como câmera de primeira pessoa) ou apontar a câmera para um personagem e mantê-los à vista (conhecidos como câmera de terceira pessoa).

Essa é a premissa básica de uma câmera 3D: uma câmera virtual que você pode usar para percorrer uma cena 3D e renderizar as imagens de um ponto de vista específico.

Compreendendo o espaço mundial e visualizando o espaço

Para codificar esse tipo de comportamento, você renderiza o conteúdo do mundo 3D do ponto de vista da câmera, não apenas do ponto de vista do sistema de coordenadas do mundo ou de algum outro ponto de vista fixo.

De um modo geral, uma cena 3D contém um conjunto de modelos 3D. Os modelos são definidos como um conjunto de vértices e triângulos, referenciados ao seu próprio sistema de coordenadas. O espaço no qual os modelos são definidos é chamado de espaço do modelo (ou local).

Após colocar os objetos do modelo em uma cena 3D, você transformará os vértices desses modelos usando uma matriz "transformação do mundo". Cada objeto tem sua própria matriz mundial que define onde o objeto está no mundo e como ele é orientado.

Esse novo sistema de referência é chamado de "espaço mundial" (ou espaço global). Uma maneira simples de gerenciá-lo é associando uma matriz de transformação do mundo a cada objeto.

Para implementar o comportamento de uma câmera 3D, você precisará executar etapas adicionais. Você fará referência ao mundo - não à origem do mundo - mas ao sistema de referência da própria câmera 3D.

Uma boa estratégia envolve tratar a câmera como um objeto 3D real no mundo 3D. Como qualquer outro objeto 3D, você usa uma matriz de "transformação do mundo" para colocar a câmera na posição e orientação desejadas no mundo 3D. A matriz de transformação do mundo da câmera transforma o objeto da câmera do original, olhando a rotação para a frente (ao longo do eixo z), para a posição real do mundo (xc, yc, zc) e a rotação do mundo.

A figura a seguir mostra as relações entre o sistema de coordenadas do mundo (x, y, z) e o sistema de coordenadas do modo de exibição (câmera) (x ', y', z ').

insira a descrição da imagem aqui

Md Mahbubur Rahman
fonte
5
As outras respostas estão lá. Você não precisa editá-los por conta própria.
Jesse Dorsey
1
@ Noctrine, Obrigado. Não sabia para mim como criar links entre páginas.
Md Mahbubur Rahman
"Na próxima seção, você usará esta fórmula de projeção em perspectiva no ActionScript que pode ser usada em seus projetos em Flash 3D." Como não há menção de um projeto Flash 3D na pergunta original, isso me faz pensar que você copiou e colou isso de outro lugar, o que é bom, se você citar suas fontes.
Gilles
@ Gilles, desculpe pelo meu erro. Eu editei minha resposta. Eu preparei a resposta estudando várias fontes. E muito obrigado a você, como você apontou. :)
Md Mahbubur Rahman
Observe que glMatrixMode()e mais algumas funções mencionadas em: eng.utah.edu/~cs6360/Lectures/frustum.pdf e opengl.org/archives/resources/faq/technical/viewing.htm estão obsoletas. Contudo, a descrição matemática permanece correta e útil.
Patryk.beza 24/10/2015
28

A resposta de Mahbubar R Aaman é bastante correta e os links que ele fornece explicam a matemática com precisão, mas no caso de você querer uma resposta menos técnica / matemática, tentarei uma abordagem diferente.

As posições dos objetos no mundo real e no mundo do jogo são definidas com algum sistema de coordenadas. Um sistema de coordenadas dá significado aos valores de posição. Se eu lhe disser que estou em "100,50", isso não ajudará, a menos que você saiba o que esses números significam (são milhas, quilômetros, latitude e longitude etc.). Se são coordenadas cartesianas (o tipo "normal" de coordenadas), você também precisa saber a que origem elas são relativas; se eu disser "estou a 100 pés para o leste", você precisará saber "leste do quê ", que é chamado de origem das coordenadas.

Existe uma maneira fácil de pensar nisso. Você poderia dizer a alguém "a estação de trem fica a 3 km ao norte e 1,5 km a leste do canto sudoeste da cidade". Você também pode dizer a alguém "a estação de trem fica a 1,6 km diretamente ao norte de onde estou agora". Ambas as coordenadas estão corretas e identificam a localização do mesmo ponto de referência, mas são medidas de uma origem diferente e, portanto, têm valores numéricos diferentes.

Em um aplicativo 3D, geralmente existe um sistema de coordenadas "mundo", usado para representar a posição da câmera e os objetos no jogo, medidos com coordenadas cartesianas com alguma origem arbitrária especificada pelo designer (geralmente o centro de qualquer nível) ou mapa que você está jogando). Existem outros sistemas de coordenadas no jogo, como o sistema de coordenadas cartesianas com a câmera na origem. Você pode definir qualquer novo sistema de coordenadas da maneira que desejar, a qualquer hora e isso é feito com muita frequência na simulação em 3D para facilitar as coisas para a matemática.

O algoritmo que realmente renderiza um triângulo individual na tela funciona de uma maneira específica e, portanto, não é conveniente trabalhar diretamente com as coordenadas do mundo durante a renderização. A matemática não está realmente configurada para lidar com informações como "o objeto está a 100 unidades à direita do centro do mundo". A matemática quer trabalhar com "o objeto está diretamente na frente da câmera e a 20 unidades de distância". Portanto, uma etapa adicional é adicionada à matemática de renderização para tomar posições no mundo dos objetos e convertê-las no sistema de coordenadas da câmera.

Claro que a câmera também tem uma posição e uma orientação. Portanto, se um objeto está na posição 20.100,50 e a câmera está na posição 10.200, -30, a posição do objeto em relação à câmera é 10.100,80 (a posição do objeto menos a posição da câmera). Quando a câmera se move em um jogo, a posição da câmera nas coordenadas do mundo é movida exatamente como você esperaria.

Observe que os objetos não são movidos; eles estão ficando exatamente onde estavam antes. No entanto, sua posição agora está sendo expressa em relação a uma origem de coordenadas diferente. As coordenadas do mundo do objeto só se movem se o objeto em si se move, mas as coordenadas da câmera também mudam sempre que a câmera se move, pois são relativas à posição da câmera.

Observe também que a descrição do tutorial que você está citando é uma explicação simplificada e não necessariamente uma descrição precisa do que o OpenGL faz. Não acho que o autor do artigo tenha entendido isso; o autor apenas tentou usar uma analogia simplificada que, nesse caso, causava confusão em vez de eliminá-la.

Se ajudar a entender por que a matemática se importa com as coordenadas da câmera, tente este exercício: levante as mãos tocando os polegares e os dedos indicadores juntos para formar um retângulo (vamos chamar de "janela de visualização") e olhe em volta para a sala em que você está Encontre um objeto e olhe para ele, depois olhe ao seu redor, mas não diretamente. Ao fazer isso, pergunte-se: "onde está o objeto na minha janela de exibição?" Esse objeto tem alguma longitude e latitude específica do mundo real que você pode usar para identificar sua localização na Terra, mas isso não diz nada sobre o que você está vendo. Dizer "o objeto está no canto superior esquerdo da minha janela e parece estar a cerca de 2 metros de distância" diz um pouco, no entanto. Você criou um sistema de coordenadas em relação à sua cabeça e à direção em que re olhando que define onde um objeto de acordo com sua visão. É basicamente disso que a parte rasterizador de triângulo do OpenGL / Direct3D precisa, e é disso que a matemática exige que as posições e a orientação do objeto sejam transformadas de suas convenientes coordenadas mundiais em coordenadas de câmera.

Sean Middleditch
fonte
Embora para mim a explicação matemática seja clara e compreensível, essa também é uma ótima explicação! Acredito que você ajudou muitos outros com a mesma pergunta.
Danijar 28/10/12
+1 para deixar claro se a câmera se move ou se o mundo é apenas uma função de qual sistema de coordenadas você está falando.
precisa
11

Apenas adicionando às outras duas (excelentes) respostas, algumas explicações adicionais sobre um ponto em que Mahbubur R Aaman abordou: "não há câmera".

Isso é verdade e representa uma falha na analogia comum da "câmera", porque a "câmera" não existe realmente. É importante perceber que a analogia da câmera é exatamente isso - uma analogia. Não descreve (nem pretende descrever) a maneira como as coisas realmente funcionam nos bastidores.

Portanto, veja (trocadilhos) como um meio de ajudá-lo a entender esse assunto, se é novo para você, mas lembre-se sempre de que é apenas um ajudante e não qualquer tipo de descrição da maneira como as coisas realmente são.

Agora, você tem duas classes de objetos que são relevantes aqui: o ponto de vista e tudo no mundo. Você deseja aproximar o ponto de vista de alguns objetos, mas, para esse movimento, o resultado final é o mesmo se a vista se aproximar dos objetos ou se os objetos se aproximam da vista. Tudo o que você está fazendo é mudar a distância entre eles; como a distância atual é X e você deseja que a nova distância seja Y, não importa qual seja o seu movimento, desde que, após o movimento, a nova distância seja Y. Então você não está realmente se movendo, você apenas mudando a distância. (Eu não quis passar por todo Einstein neste ... honesto!)

Porém, como a câmera não existe, a única coisa que você pode alterar a distância são os objetos. Então você altera a distância dos objetos e sai o mesmo resultado. Como todos os objetos passam por transformações de qualquer maneira , isso não é mais ou menos caro.

Uma explicação matemática mais simples pode ajudar mais. Vamos fingir que todas as coordenadas são 1D - o ponto de vista está em 0, seus objetos estão em 4 e você deseja que o ponto de vista vá para 3. Isso significa que a distância entre eles mudará de 4 (4 - 0) para 1 (4 - 3) Mas como a câmera não existe, você não pode alterar esse 0; sempre será 0. Portanto, em vez de adicionar 3 a 0 (o que você não pode fazer), subtraia 3 de 4 (o que você pode fazer) - os objetos estão agora em 1 e o resultado final é o mesmo - distância entre ponto de vista e objetos é 1.

Maximus Minimus
fonte
Embora a câmera não exista como tal, você ainda pode calcular sua posição antes da transformação. Em alguns casos, no entanto (projeção paralela não alinhada ao eixo), você terminará com mais de uma das coordenadas usuais "no infinito" (positiva ou negativa), o que é menos útil que a matriz de transformação.
Martin Sojka
7

Mover a câmera ou mover o mundo são duas opções igualmente válidas que equivalem à mesma coisa. No final do dia, você está mudando de um sistema de coordenadas para outro. As respostas acima estão corretas, mas de que maneira você as visualiza são dois lados da mesma moeda. As transformações podem ir de qualquer maneira - elas são apenas o inverso uma da outra.

Parte do processo de renderização converte as coordenadas do mundo em coordenadas oculares. No entanto, uma maneira fácil de modelar isso é com um objeto de câmera virtual em seu aplicativo. A câmera pode representar a matriz de projeção (que é responsável pelo efeito de perspectiva) e também a matriz de visualização que é usada para converter do espaço do mundo para o espaço dos olhos.

Portanto, embora o sombreador de vértice use a matriz de vista para alterar as coordenadas de sua geometria para o espaço visual, geralmente é mais fácil pensar em um objeto de câmera se movendo pelo seu mundo virtual que, à medida que se move, recalcula a matriz de vista.

Assim, em sua aplicação, você move a câmera em cordas mundiais, atualiza a matriz de visão das câmeras, passa a nova matriz de visão para o sombreador de vértice como um uniforme ou parte de um bloco, renderiza sua cena.

Sean Harmer
fonte
5

Em vez disso, eu diria que é uma analogia defeituosa. Na sua forma mais básica, "mover a câmera" e "mover o mundo" são exatamente o mesmo construto matemático - é apenas mais fácil pensar em mover o mundo conceitualmente, especialmente quando se trata de transformações hierárquicas. Basicamente, você está movendo o mundo pela câmera apenas no sentido de traduzir os vértices do mundo no espaço de coordenadas da câmera - mas essa é uma transformação afim reversível.

No entanto, quando você começa a trazer a determinação da visibilidade para o mix, a ÚLTIMA coisa que você deseja fazer é traduzir o mundo inteiro ao redor da câmera. Em vez disso, na maioria dos casos (especialmente no caso clássico de BSPs fixos ou similares), você usará a posição da câmera no mundo para consultar suas estruturas de visibilidade para determinar quais coisas provavelmente serão visíveis e depois traduzir apenas coisas no espaço de coordenadas da câmera.

fofo
fonte
4

Não acho que a afirmação seja categoricamente verdadeira, pois raramente se "move" as coordenadas do mundo em um jogo, mas na verdade altera as coordenadas da câmera virtual.

O que o conceito de câmera realmente faz é transformar o núcleo finito de visualização - que é uma pirâmide truncada com 8 pontos de canto (ou definida pela interseção de 6 planos) em um cubo de unidade, que representa o espaço do clipe nos estágios finais do openGL pipeline de renderização.

Nesse sentido, o mundo não é movido, mas apenas calculamos as coordenadas do mundo no sistema de coordenadas do espaço do clipe.

Aki Suihkonen
fonte
2

Mover a câmera ou mover o mundo são duas opções igualmente válidas (e ambas são verdadeiras). No final do dia, estamos mudando de um sistema de coordenadas para outro. As transformações podem ir de qualquer maneira - elas são apenas o inverso uma da outra.

CoolProgrammer
fonte
2

Muitas boas respostas aqui. Vou tentar não repetir nenhum deles. Às vezes, é mais fácil pensar em termos de câmera, como o Direct3D faz isso (nota: não reproduzi muito do post 9.0c)

"Mover o mundo", como no sentido de Futurama, de que alguém citado é uma ótima maneira de vê-lo ("Os motores não movem o navio de maneira alguma. O navio permanece onde está e os motores movem o universo ao redor" isto!"). Na verdade, isso era bastante comum em jogos 2D. Você literalmente tinha uma janela de visualização que dificilmente poderia ser ajustada, e que às vezes era a RAM do seu vídeo ou uma janela da interface do usuário. Se o OpenGL faz isso por esse tipo de razão, é difícil dizer.

Você também pode pensar em um movimento 2D em termos de câmera, e esse tipo de processo de pensamento pode facilitar a descoberta de efeitos.

Joe Plante
fonte
1
Tarde, mas boa resposta também!
Danijar
Obrigado! Eu sempre achei que a adição à discussão sobre as páginas que são encontrados através de um motor de busca vir a ser muito apreciada, especialmente se a informação é útil ou interessante
Joe Plante
2

Parece haver muitos mal-entendidos aqui, a partir dos autores dos documentos do OpenGL ...

Deixe-me restaurar rapidamente sua sanidade: o mundo não se move , permanece em pé. Quem tentar implementar o mundo como se movimentar pelo jogador rapidamente terá problemas no modo multiplayer. Sem mencionar que atualizar as posições de milhões (ou bilhões) de objetos no mundo ao movimento de cada jogador fará uma jogabilidade bastante lenta ...

Então, o que realmente acontece lá, e o que há com a citação?

Bem, primeiro você precisa entender o conceito de um sistema de coordenadas. Geralmente, você escolhe um ponto no mundo e declara ser a "origem", ou seja, um ponto com coordenadas (0,0,0). Você também escolhe três direções "principais", que você chama de X, Y e Z. Obviamente, existem várias maneiras de atribuir um sistema de coordenadas. Geralmente, existe um "sistema de coordenadas mundiais"; nesse sistema, o mundo é estacionário (mais ou menos). Em um jogo, esse sistema seria escolhido pelo designer de níveis.

Agora, também é conveniente considerar outro sistema de coordenadas, ligado ao olho do jogador. Neste sistema de coordenadas, o jogador está sempre nas coordenadas (0,0,0), e o mundo se move e gira em torno dele. Portanto, a cotação está correta se você entender como sendo feita no sistema de coordenadas do jogador .

No entanto, o mundo não opera nas coordenadas do jogador, ele opera nas coordenadas do mundo. E onde dois sistemas de coordenadas estão envolvidos, sempre há uma maneira de transformar um tipo de coordenadas no outro. No OpenGL, isso é feito usando uma matriz de visualização 4x4.

Por fim, quando um jogador se move, o mundo permanece parado enquanto o jogador é movido. Isso é nas coordenadas do mundo, da maneira como os objetos são armazenados no seu jogo. O jogador também tem uma câmera de visão associada a ele, e esta câmera se move de maneira semelhante ao redor do mundo (apesar do que os documentos do OpenGL parecem estar dizendo). No entanto, para mostrar o mundo na tela do usuário, as coordenadas de todos os objetos visíveis são convertidas no sistema de coordenadas do jogador usando uma matriz de transformação e, em seguida, projeção adicional é aplicada para criar um efeito de perspectiva. No sistema de coordenadas desse jogador, o mundo parece realmente se mover pelo jogador. Mas é apenas uma maneira extremamente inútil e confusa de pensar sobre isso.

Paxá
fonte
" começando pelos escritores dos documentos do OpenGL " Certo, porque tenho certeza de que os criadores do OpenGL são obviamente estúpidos demais para entender a diferença entre a apresentação de um mundo (o que interessa ao OpenGL) e a representação conceitual desse mundo ( que não é algo que o OpenGL lida com).
Nicol Bolas
Mas é apenas uma maneira extremamente inútil e confusa de pensar sobre isso. ” Também é a verdade . E a verdade é sempre mais útil do que uma mentira. Porque, mais cedo ou mais tarde, essa mentira o alcançará e você terá que enfrentar a verdade.
Nicol Bolas