Three.js: Cálculo del campo de visión de la cámara de perspectiva

Creado en 2 feb. 2012  ·  19Comentarios  ·  Fuente: mrdoob/three.js

Como no tengo experiencia previa con 3D, me encontré con algunos problemas que podrían ser de conocimiento común para los profesionales de 3D;).
Tengo una amplia variedad de tamaños de escena (800x600, 1200x100, etc.).
¿Qué fórmula puedo usar para asegurarme de que un objeto con una posición z de 0 y un ancho y alto que sea el mismo que el de la escena ocupe toda la escena?

Por ejemplo: Object Mesh A es 1200x100 y está en la posición Z 0. La escena también es 1200x100. La cámara está en la posición z 1500. ¿Cuál es el campo de visión para que el objeto llene la escena?

Algo en la línea de ((A / B) * C) es lo que estoy buscando: D.

Cantidad infinita de felicitaciones para quien sea lo suficientemente brillante como para responder a mi pregunta :)

Question

Comentario más útil

El height visible dado el campo de visión vertical vFOV y la distancia desde la cámara dist es

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

El width visible es

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

El parámetro de campo de visión de la cámara en THREE.js es el vertical.

Utilice los dos conjuntos de ecuaciones para calcular dos veces el vFOV requerido y seleccione la respuesta más grande.

Todos 19 comentarios

El height visible dado el campo de visión vertical vFOV y la distancia desde la cámara dist es

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

El width visible es

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

El parámetro de campo de visión de la cámara en THREE.js es el vertical.

Utilice los dos conjuntos de ecuaciones para calcular dos veces el vFOV requerido y seleccione la respuesta más grande.

Muchas gracias por responder :)
Aunque estoy un poco confundido. ¿De dónde obtengo la variable vFOV?
¿Es la altura del objeto lo que debería llenar la escena?
Si es así, obtengo números extraños (en el rango de 1000), entonces, ¿cómo puedo traducir eso al campo de visión final?

Creé un violín http://jsfiddle.net/dmYgr/6/
¿Puedes mostrarme allí cómo hacer esto?

De nuevo muchas gracias. Por tu publicación ya puedo sentir que eres más genio que yo;)

Use la primera ecuación y resuelva para vFOV , luego use eso como el parámetro fov para la cámara.

Mi escena es 800 * 600.
La distancia de la cámara es 1000.

¿Cómo uso estos números en su fórmula?
No sé qué rellenar en vFOV.

altura = 2 * Math.tan ((vFOV / 2)) * dist; <- Me está diciendo que empiece aquí, pero ¿qué número debería reemplazar al vFOV?

Usa la primera ecuación y resuelve vFOV así

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

luego utilícelo como el parámetro fov para la cámara.

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 no es un 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 tampoco es un FOV válido

¿Puede completar el ejemplo para mí y mostrar un ejemplo que dé un número de FOV válido?
El número correcto del ejemplo anterior es alrededor de 37

En tu violín

altura = altura de la malla de su avión = 500.

distancia = cámara.z - plano.z = 1000 - 100 = 900.

vFOV = 2 * Math.atan (altura / (2 * distancia)) = 0,5419 radianes o 31,04 grados.

2 * Math.atan (500 / (2 * 900)) = 0.5418937006768411 según mi navegador (google chrome)

Lo siento, olvidé mostrar la conversión de radianes a grados. Actualicé mi publicación anterior.

¡Muchas gracias! :RE
Ja, tomó como 10 respuestas pero ahora funciona :).
¡Gracias de nuevo!

@Tobiasartz :-)

West Langley. Tu eres un rey Gracias.

¡Esto fue muy útil! ¡Gracias @WestLangley !

¡Gracias @WestLangley !
Como me tomó un tiempo darme cuenta de que necesitaba agregar una conversión de radiantes a grados, agrego aquí un ejemplo con el 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 Su fórmula no tiene sentido. window.innerHeight tiene unidades de píxeles. distance probablemente no. La altura visible debe tener las mismas unidades que la distancia.

Actualicé el violín de Tobiasartz con esa fórmula y parece funcionar:
http://jsfiddle.net/dmYgr/63/
El lienzo mide 500 px, el plano 495x495 y tiene aproximadamente 5 px de borde alrededor.
¿Por qué 1000px no es una distancia válida?

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

¿Por qué 1000px no es una distancia válida?

¿Alguna vez ha colocado una cámara de 1000 píxeles frente a su sujeto?

Puede colocar una cámara real a 10 pies de distancia para ver una escena de 10 pies de ancho. De manera similar, puede colocar una cámara virtual a 1000 px de distancia para ver una escena de 1000 px de ancho.

Utilizo esto cuando sé la altura, el ancho de la escena y la distancia de la cámara ...

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;

De esta manera situaciones como altura> ancho también se manejan ...

¿Fue útil esta página
0 / 5 - 0 calificaciones

Temas relacionados

konijn picture konijn  ·  3Comentarios

seep picture seep  ·  3Comentarios

ghost picture ghost  ·  3Comentarios

jlaquinte picture jlaquinte  ·  3Comentarios

fuzihaofzh picture fuzihaofzh  ·  3Comentarios