cámara ortográfica three.js: amplía todo para obtener un cubo con perspectiva
He desarrollado un simplethree.js
aplicación que renderiza un cubo. He creado tres archivos:index.html
, viewer_style.css
yviewer.js
.
El contenido deindex.html
es el siguiente:
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8>
<title>My first three.js app</title>
<link rel='stylesheet' type='text/css' href='viewer_style.css'>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="js/three.js"></script>
<script src="js/controls/OrbitControls.js"></script>
<script src="js/renderers/Projector.js"></script>
</head>
<body>
<script src="viewer.js"></script>
</body>
</html>
Y el contenido deviewer.js
es el siguiente:
// SCENE
var scene = new THREE.Scene();
// CAMERA
var frustumHeight;
var aspect = window.innerWidth / window.innerHeight;
var camera = new THREE.OrthographicCamera(- frustumHeight * aspect / 2, frustumHeight * aspect / 2, frustumHeight / 2, - frustumHeight / 2, 1, 2000 );
camera.position.x = 0;
camera.position.y = 0;
camera.position.z = 100;
// CUBE
var geometry = new THREE.BoxGeometry( 1, 1, 1 );
var material = new THREE.MeshPhongMaterial({color: 0xbaf5e8, flatShading: true});
var cube = new THREE.Mesh( geometry, material );
cube.receiveShadow = true;
scene.add(cube);
// BOUNDING BOX
var helper_bbox = new THREE.BoxHelper(cube);
helper_bbox.update();
scene.add(helper_bbox);
// AXES
var helper_axes = new THREE.AxisHelper();
scene.add(helper_axes);
// FIT ALL:
var bbox_radius = helper_bbox.geometry.boundingSphere.radius;
if(aspect < 1){
frustumHeight = 2 * bbox_radius;
}
else{
frustumHeight = 2 * bbox_radius / aspect;
}
camera.left = - frustumHeight * aspect / 2;
camera.right = frustumHeight * aspect / 2;
camera.top = frustumHeight / 2;
camera.bottom = - frustumHeight / 2;
camera.updateProjectionMatrix();
// RENDERER
var renderer = new THREE.WebGLRenderer({alpha: true});
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFShadowMap;
// LIGHTS
var ambientLight = new THREE.AmbientLight(0x101010, 1.0);
scene.add(ambientLight);
directionalLight = new THREE.DirectionalLight(0xffffff, 1.0);
directionalLight.position.set(1.0, 1.0, 1.0).normalize();
scene.add(directionalLight);
directionalLight_2 = new THREE.DirectionalLight(0xffffff, 1.0);
directionalLight_2.position.set(-1.0, -1.0, 1.0).normalize();
scene.add(directionalLight_2);
// CONTROLS
document.body.appendChild(renderer.domElement);
var controls = new THREE.OrbitControls(camera);
window.addEventListener( 'resize', onWindowResize, false );
function animate(){
requestAnimationFrame(animate);
renderer.render(scene, camera);
}
function onWindowResize(){
var aspect = window.innerWidth / window.innerHeight;
camera.left = - frustumHeight * aspect / 2;
camera.right = frustumHeight * aspect / 2;
camera.top = frustumHeight / 2;
camera.bottom = - frustumHeight / 2;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
camera.lookAt(scene.position);
}
animate();
Tengo la intención de ajustar el cubo a la escena con un cierto margen utilizando el radio de la esfera delimitadora del cubo. Parece funcionar correctamente, como se puede ver en la siguiente imagen:
Sin embargo, cambié la posición de la cámara enviewer.js
a lo siguiente:
camera.position.x = 100;
camera.position.y = 100;
camera.position.z = 100;
En esta situación, obtengo algo como esto:
En este caso, el cubo no se ajusta a la pantalla. Creo que esto se debe al hecho de que estoy midiendo el radio de la esfera delimitadora en el sistema de referencia incorrecto. Sin embargo, no he podido encontrar una solución a este problema.
¿Alguien sabe lo que estoy haciendo mal? ¿Estoy usando el enfoque correcto? Gracias por adelantado.