【发布时间】:2018-02-10 07:20:57
【问题描述】:
我开发了一个简单的three.js 应用程序来渲染一个立方体。我创建了三个文件:index.html、viewer_style.css 和 viewer.js。
index.html的内容如下:
<!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>
而viewer.js的内容如下:
// 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();
我打算使用立方体的边界球体的半径以一定的边距使立方体适合场景。它似乎工作正常,如下图所示:
但是,我将viewer.js 中的摄像头位置更改为以下:
camera.position.x = 100;
camera.position.y = 100;
camera.position.z = 100;
在这种情况下,我会得到这样的结果:
在这种情况下,立方体不适合屏幕。我认为这是因为我在错误的参考系中测量边界球的半径。但是,我无法找到解决此问题的方法。
有谁知道我做错了什么?我是否使用了正确的方法?提前致谢。
【问题讨论】:
-
您的代码看起来不错。将
aspect < 1更改为aspect > 1。为清楚起见,将frustumSize重命名为frustumHeight。 -
谢谢。我编辑了问题,将
frustumSize更改为frustumHeight。我也尝试将aspect < 1更改为aspect > 1,但我也没有得到想要的结果。事实上,立方体现在在屏幕上更大了。我没有在问题中添加最后一个更改,因为我不太明白您为什么建议进行此更改。
标签: javascript three.js orthographic projection-matrix