正交投影摄像机和透视投影摄像机
区别正交投影摄像机:透视投影摄像机:
属性正交投影摄像机Orthographic Camera:透视投影摄像机PerspectiveCamera:
实例需求过程结果完整代码总结
区别
正交投影摄像机:
所有物体被渲染出来的尺寸是一样的,没有近大远小之分。因为对象相对于摄像机的距离对渲染的结果是没有影响的。常用于二维游戏中。
透视投影摄像机:
透视试图,近大远小。更贴近真实世界。
属性
正交投影摄像机Orthographic Camera:
构造函数:
THREE.OrthographicCamera(left, right, top, bottom, near, far)
参数描述left(左边界)可视范围的左平面,渲染部分的左边界。right(右边界)可渲染区域的另一边界top(上边界)可渲染区域的最上面bottom(下边界)可渲染区域的最下面near(近面距离)基于摄像机所处的位置,从这一点开始渲染far(远面距离)基于摄像机所处的位置,渲染场景到这一点结束zoom(变焦)放大和缩小场景(默认值为1,小于1—缩小,大于1—放大,负数场景会上下颠倒)
透视投影摄像机PerspectiveCamera:
构造函数:
THREE.PerspectiveCamera(fov,aspect,near,far,zoom)
参数描述fov视场。摄像机能够看到的那部分场景。一般计算机不能完全显示能够看到的景象,所以一般会选择较小的区域。推荐默认值:50aspect(长宽比)渲染结果的横向尺寸和纵向尺寸的比值。推荐默认值:window.innerWidth/window.innerHeightnear(近面距离)定义从距离摄像机多近的距离开始渲染。推荐默认值:0.1far(远面距离)定义了摄像机从它所处的位置能够看多远。推荐默认值:100zoom(变焦)放大和缩小场景(默认值为1,小于1—缩小,大于1—放大,负数场景会上下颠倒)
实例
需求
在Three.js中改变摄像机,通过点击按钮SwitchCamera时,透视摄像机变成正交摄像机。
过程
构建基本场景(scene,camera,renderer,plane,spotLight,ambientLight)添加立方体(平铺整个平面)添加初始化性能插件、dat.GUI简化实验流程添加用户交互插件窗口触发函数(页面响应式布局)
结果
完整代码
content="width=device-width,initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no,minimal-ui">
html, body {
margin: 0;
height: 100%;
}
//初始化场景
var scene;
function initScene() {
scene = new THREE.Scene();
}
//摄像机
var camera;
function initCamera() {
//初始化摄像机为透视摄像机,设置fov(视场)、aspect(长宽比)、near(近面距离)、far(远面距离)
camera = new THREE.PerspectiveCamera(45,window.innerWidth / window.innerHeight,0.1,1000);
//摄像机的位置
camera.position.set(120,60,180);
//摄像机所指向的位置
camera.lookAt(scene.position);
}
//渲染器
var renderer;
function initRender(){
//创建渲染器
renderer = new THREE.WebGLRenderer();
//颜色
renderer.setClearColor(new THREE.Color(0x000000));
//大小
renderer.setSize(window.innerWidth,window.innerHeight);
//将渲染的结果添加到HTML框架的body中
document.body.appendChild(renderer.domElement);
}
//平面
var plane;
//平面Geometry
var planeGeometry = new THREE.PlaneGeometry(180,180);
function initPlane(){
//平面的材质
var planeMaterial = new THREE.MeshLambertMaterial({
color: 0xffffff,
});
plane = new THREE.Mesh(planeGeometry, planeMaterial);
//旋转平面水平放置
plane.rotation.x = -0.5*Math.PI;
//设置平面位置
plane.position.set(0,0,0);
//将平面添加至场景
scene.add(plane);
}
//光源
var light;
function initLight(){
//场景添加一个环境光
scene.add(new THREE.AmbientLight(0x292929));
//添加平行光
light = new THREE.DirectionalLight(0xffffff,0.7);
light.position.set(-20,40,60);
scene.add(light);
}
//方块
var cube;
function initCube(){
//方块大小
var cubeGeometry = new THREE.BoxGeometry(4,4,4);
//两个for循环添加立方体平铺整个平面
for(var j=0;j<(planeGeometry.parameters.height/5);j++){
for(var i=0;i var rnd = Math.random()*0.75+0.25; var cubeMaterial = new THREE.MeshLambertMaterial(); cubeMaterial.color = new THREE.Color(rnd,0,0); cube = new THREE.Mesh(cubeGeometry,cubeMaterial); //立方体的位置 cube.position.set( -((planeGeometry.parameters.width)/2)+2+(i*5), 2, -((planeGeometry.parameters.height)/2)+2+(j*5)); //添加至场景中 scene.add(cube); } } } //初始化性能插件 var stats; function initStats(){ stats = new Stats(); document.body.appendChild(stats.domElement); } //使用dat.GUI简化实验流程 var trackballControls; var controls; function initControls(){ controls = new function(){ this.perspective = "Perspective"; this.switchCamera = function (){ //if语句判断当前相机类型 if(camera instanceof THREE.PerspectiveCamera){ camera = new THREE.OrthographicCamera(window.innerWidth/-16, window.innerWidth/16, window.innerHeight/16, window.innerHeight/-16, -200,500); camera.position.set(120,60,180); camera.lookAt(scene.position); //摄像机控制函数 initInteraction(); this.perspective = "Orthographic"; } else{ camera = new THREE.PerspectiveCamera(45,window.innerWidth/window.innerHeight,0.1,1000); camera.position.set(120,60,180); camera.lookAt(scene.position); initInteraction(); this.perspective = "Perspective"; } }; }; var gui = new dat.GUI(); gui.add(controls,'switchCamera'); gui.add(controls,'perspective').listen(); //gui窗口的位置设置 //gui.domElement.style.position = 'absolute'; //gui.domElement.style.right = '300px'; //gui.domElement.style.top = 0; } //摄像机控制函数 //用户交互插件 鼠标左键按住旋转,右键按住平移,滚轮缩放 var interaction; function initInteraction() { //轨道控制器 interaction = new THREE.OrbitControls( camera, renderer.domElement ); //是否可以缩放 interaction.enableZoom = true; //是否自动旋转 interaction.autoRotate = true; //是否开启右键拖拽 interaction.enablePan = true; } //窗口触发函数 function onWindowResize(){ //更新相机的长宽比aspect属性 camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); //对于渲染器,需要改变它的尺寸大小 renderer.setSize(window.innerWidth,window.innerHeight); } function render(){ //告诉摄像机使用指定的摄像机渲染场景 renderer.render(scene,camera); } function animate(){ //更新控制器 render(); //更新性能插件 stats.update(); requestAnimationFrame(animate); } function draw(){ initScene(); initCamera(); initRender(); initPlane(); initLight(); initCube(); initControls(); initInteraction(); initStats(); animate(); window.onresize = onWindowResize; } 总结 正交投影摄像机和透视投影摄像机的切换,首先用instanceof判断目前摄像机是否是透视摄像机 如果是透视投影摄像机,则用 camera = new THREE.OrthographicCamera(left, right, top, bottom, near, far) 设置为正交投影摄像机,反之亦然 后续可以继续设置摄像机的位置,对准场景中心。 好文链接
发表评论