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 :)
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?
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 ...
Comentários muito úteis
O
height
visível dado o campo de visão verticalvFOV
e a distância da câmeradist
éO
width
visível é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.