Three.js: Calculando o FOV para a câmera em perspectiva

Criado em 2 fev. 2012  ·  19Comentários  ·  Fonte: mrdoob/three.js

Como não tenho experiência anterior com 3D, me deparo com alguns problemas que podem ser do conhecimento comum para vocês profissionais de 3D;).
Tenho uma grande variedade de tamanhos de cena (800x600, 1200x100 etc.).
Que fórmula posso usar para ter certeza de que um objeto com uma posição z de 0 e uma largura e altura iguais à da cena preenche toda a cena.

Ex: Object Mesh A é 1200x100 e está na posição Z 0. A cena também é 1200x100. A câmera está na posição z 1500. Qual é o FOV para fazer o objeto preencher a cena?

Algo na linha de ((A / B) * C) é o que estou procurando: D.

Uma quantidade infinita de elogios a quem for brilhante o suficiente para responder à minha pergunta :)

Question

Comentários muito úteis

O height visível dado o campo de visão vertical vFOV e a distância da câmera dist é

height = 2 * Math.tan( ( vFOV / 2 ) ) * dist;

O width visível é

aspect = window_width / window_height;
hFOV = 2 * Math.atan( Math.tan( vFOV / 2 ) * aspect );
width  = 2 * Math.tan( ( hFOV / 2 ) ) * dist;

O parâmetro do campo de visão para a câmera em THREE.js é o vertical.

Use os dois conjuntos de equações para calcular o vFOV necessário duas vezes e selecione a resposta maior.

Todos 19 comentários

O height visível dado o campo de visão vertical vFOV e a distância da câmera dist é

height = 2 * Math.tan( ( vFOV / 2 ) ) * dist;

O width visível é

aspect = window_width / window_height;
hFOV = 2 * Math.atan( Math.tan( vFOV / 2 ) * aspect );
width  = 2 * Math.tan( ( hFOV / 2 ) ) * dist;

O parâmetro do campo de visão para a câmera em THREE.js é o vertical.

Use os dois conjuntos de equações para calcular o vFOV necessário duas vezes e selecione a resposta maior.

Muito obrigado por responder :)
Estou meio confuso. De onde obtenho a variável vFOV?
É a altura do objeto que deveria preencher a cena?
Em caso afirmativo, estou obtendo números estranhos (na faixa de 1000), então como faço para traduzir isso para o eventual FOV.

Eu criei um Fiddle http://jsfiddle.net/dmYgr/6/
Você pode me mostrar como fazer isso?

Mais uma vez, muito obrigado. Pela sua postagem, já posso sentir que você é mais gênio do que eu;)

Use a primeira equação e resolva vFOV , então use isso como o parâmetro fov para a câmera.

Minha cena é 800 * 600.
A distância da câmera é 1000.

Como faço para usar esses números em sua fórmula.
Não sei o que preencher no vFOV.

altura = 2 * Math.tan ((vFOV / 2)) * dist; <- Você está me dizendo para começar aqui, mas qual número deve substituir o vFOV?

Use a primeira equação e resolva vFOV assim

vFOV = 2 * Math.atan( height / ( 2 * distance ) );

em seguida, use-o como o parâmetro fov para a câmera.

var renderWidth = 800;
var renderHeight = 600;
var cameraPosition = 1000;
var vFOV = 2 * Math.atan( renderWidth / ( 2 * cameraPosition ) );
var height = 2 * Math.tan( ( vFOV / 2 ) ) * cameraPosition;
var aspect = renderWidth / renderHeight;
var hFOV = 2 * Math.atan( Math.tan( vFOV / 2 ) * aspect );
var width  = 2 * Math.tan( ( hFOV / 2 ) ) * cameraPosition;

Resultado:
vFOV = 0,7610127542247298 que não é um FOV válido

var vFOV = 2 * Math.atan( renderHeight / ( 2 * cameraPosition ) );
var height = 2 * Math.tan( ( vFOV / 2 ) ) * cameraPosition;

var aspect = renderWidth / renderHeight;
var hFOV = 2 * Math.atan( Math.tan( vFOV / 2 ) * aspect );
var width  = 2 * Math.tan( ( hFOV / 2 ) ) * cameraPosition;

vFOV = 0,5829135889557342 que também não é um FOV válido

Você pode preencher o exemplo para mim e mostrar um exemplo que forneça um número FOV válido?
O número correto do exemplo acima é algo em torno de 37

Em seu violino,

altura = altura da malha do seu plano = 500.

distância = camera.z - plane.z = 1000 - 100 = 900.

vFOV = 2 * Math.atan (altura / (2 * distância)) = 0,5419 radianos ou 31,04 graus.

2 * Math.atan (500 / (2 * 900)) = 0,5418937006768411 de acordo com meu navegador (google chrome)

Desculpe, esqueci de mostrar a conversão de radianos para graus. Eu atualizei meu post anterior.

Muito obrigado! : D
Hah, demorou cerca de 10 respostas, mas funciona agora :).
Obrigado novamente!

@Tobiasartz :-)

West Langley. Você é um rei. Obrigado.

Isso foi super útil !! Obrigado @WestLangley !

Obrigado @WestLangley !!
Como demorei um pouco para perceber que precisava adicionar uma conversão de radiantes em graus, estou adicionando aqui um exemplo com o código final:

var distance = 1000;
var FOV = 2 * Math.atan( window.innerHeight / ( 2 * distance ) ) * 180 / Math.PI;
var camera = new THREE.PerspectiveCamera( FOV, window.innerWidth/window.innerHeight, 0.1, distance );
camera.position.z = distance;

@ Emanuele-Spatola Sua fórmula não faz sentido. window.innerHeight tem unidades de pixels. distance provavelmente não. A altura visível deve ter as mesmas unidades da distância.

Eu atualizei o violino de Tobiasartz com essa fórmula e parece funcionar:
http://jsfiddle.net/dmYgr/63/
A tela tem 500px, o avião tem 495x495 e cerca de 5px de borda ao redor dela.
Por que 1000px não é uma distância válida?

http://jsfiddle.net/dmYgr/65/

Por que 1000px não é uma distância válida?

Você já colocou uma câmera de 1000 pixels na frente do seu assunto?

Você pode colocar uma câmera real a 3 metros de distância para ver uma cena de 3 metros de largura. Da mesma forma, você pode colocar uma câmera virtual de 1000px de distância para visualizar uma cena de 1000px de largura.

Eu uso isso quando sei a altura, largura da cena e distância da câmera ...

var distance = 1000,height=window.innerHeight,width=window.innerWidth
var diag = Math.sqrt((height*height)+(width*width))
var FOV = 2 * Math.atan( diag / ( 2 * distance ) ) * 180 / Math.PI;
var camera = new THREE.PerspectiveCamera( FOV, window.innerWidth/window.innerHeight, 0.1, distance );
camera.position.z = distance;

Desta forma, situações como altura> largura também são tratadas ...

Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

akshaysrin picture akshaysrin  ·  3Comentários

zsitro picture zsitro  ·  3Comentários

donmccurdy picture donmccurdy  ·  3Comentários

danieljack picture danieljack  ·  3Comentários

Horray picture Horray  ·  3Comentários