Three.js教程(4):相机
相机这部分的内容并不是很多,Three.js主要支持两种相机,一种是PerspectiveCamera
即透视投影摄像机
,另一种是OrthographicCamera
即正交投影摄像机
。两种相机都是继承自Camera
对象,Camera
对象又是继承自Object3D
。
透视投影摄像机
透视投影摄像机(PerspectiveCamera)是最常用的摄像机,他跟我们的眼睛类似,越近的物体看到的越大,越远的物体看到的越小。
PerspectiveCamera的构造方法有4个参数,分别是视场、长宽比、近处距离、远处距离,其中视场表示眼睛看到的度数,比如人类可以看到前面一半左右,所以人类的视场就是180°,而火影忍者中,日向一族有一种技能叫白眼,使用该技能后其视场可以接近360°,该值默认值是50°。第二个参数长宽比一般设置为canvas.width/canvas.height
,对于长等于屏幕的长,宽等于屏幕的宽时一般是window.innerWidth/window.innerHeight
。最后两个近处的距离和远处的距离通常视情况而定,往往近处距离是0.1
远处距离是1000
。
我们先来看一个例子:
var camera, scene, renderer;
var geometry, material, mesh;
var stats = new Stats();
var gui = new dat.GUI();
var obj = {
x : 0,
y : 2,
z : 50,
rotateX : 0,
rotateY : 0,
rotateZ : 0
};
var boxSize = 1;// 宽度是1
var rowNumber = 10;// 每行10个
function init() {
camera = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 0.01, 100 );
scene = new THREE.Scene();
for (var i = 0; i < rowNumber; i++) {
for (var j = 0; j < rowNumber; j++) {
geometry = new THREE.BoxGeometry( boxSize, boxSize, boxSize );
material = new THREE.MeshNormalMaterial();
mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );
// 每个方块中间有一个空白间隙
mesh.position.x = -rowNumber * boxSize + 2 * i * boxSize;
mesh.position.z = -rowNumber * boxSize + 2 * j * boxSize;
}
}
renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
stats.showPanel(0); // 0: fps, 1: ms, 2: mb, 3+: custom
document.body.appendChild( stats.dom );
gui.add(obj, 'x', -20, 20).onChange(function (val){
camera.position.x = val;
});
gui.add(obj, 'y', -20, 20).onChange(function (val){
camera.position.y = val;
});
gui.add(obj, 'z', 0, 100).onChange(function (val){
camera.position.z = val;
});
gui.add(obj, 'rotateX', -45, 45).onChange(function (val){
camera.rotation.x = val / 180 * Math.PI;
});
gui.add(obj, 'rotateY', -45, 45).onChange(function (val){
camera.rotation.y = val / 180 * Math.PI;
});
gui.add(obj, 'rotateZ', -45, 45).onChange(function (val){
camera.rotation.z = val / 180 * Math.PI;
});
camera.position.z = obj.z;
camera.position.y = obj.y;
// 看向场景
camera.lookAt(scene.position);
}
function animate() {
stats.update();
requestAnimationFrame( animate );
renderer.render( scene, camera );
}
init();
animate();
效果如下:
这里我们唯一没有见过的API是camera.lookAt
它表示看向哪里,它需要接受一个Vector3
对象作为参数,也可以是3个参数,具体如下:
// 看向(0,1,0)
camera.lookAt(new THREE.Vector3( 0, 1, 0 ));
// 看向(0,1,0)
camera.lookAt(0, 1, 0);
// 看向某个位置 position是Object3D里面的一个属性表示位置 也是一个Vector3对象
camera.lookAt(scene.position);
正交投影摄像机
正交投影摄像机(OrthographicCamera)看到相同大小的物体,都是一样大的。其实相当于平行光照射到一个平面上的映射。
OrthographicCamera的构造方法有6个参数,分别是left、right、top、bottom、near、far
,即左边、右边、上边、下边、近处和远处的位置,6个值刚好确定了一个长方体,正是投射的长方体。
我们来看一个例子:
var camera, scene, renderer;
var geometry, material, mesh;
var stats = new Stats();
var gui = new dat.GUI();
var obj = {
x : 0,
y : 3,
z : 2,
rotateX : 0,
rotateY : 0,
rotateZ : 0
};
var boxSize = 5;
var rowNumber = 10;// 每行10个
function init() {
// camera = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 0.01, 100 );
// 以屏幕为宽高
camera = new THREE.OrthographicCamera(
window.innerWidth / -rowNumber, window.innerWidth / rowNumber,
window.innerHeight / rowNumber, window.innerHeight / - rowNumber, -300, 300 );
scene = new THREE.Scene();
for (var i = 0; i < rowNumber; i++) {
for (var j = 0; j < rowNumber; j++) {
geometry = new THREE.BoxGeometry( boxSize, boxSize, boxSize );
material = new THREE.MeshNormalMaterial();
mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );
// 每个方块中间有一个空白间隙
mesh.position.x = -rowNumber * boxSize + 2 * i * boxSize ;
mesh.position.z = -rowNumber * boxSize + 2 * j * boxSize;
}
}
renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
stats.showPanel(0); // 0: fps, 1: ms, 2: mb, 3+: custom
document.body.appendChild( stats.dom );
gui.add(obj, 'x', -100, 100).onChange(function (val){
camera.position.x = val;
});
gui.add(obj, 'y', -100, 100).onChange(function (val){
camera.position.y = val;
});
gui.add(obj, 'z', -100, 100).onChange(function (val){
camera.position.z = val;
});
gui.add(obj, 'rotateX', -45, 45).onChange(function (val){
camera.rotation.x = val / 180 * Math.PI;
});
gui.add(obj, 'rotateY', -45, 45).onChange(function (val){
camera.rotation.y = val / 180 * Math.PI;
});
gui.add(obj, 'rotateZ', -45, 45).onChange(function (val){
camera.rotation.z = val / 180 * Math.PI;
});
camera.position.z = obj.z;
camera.position.y = obj.y;
// 看向场景
camera.lookAt(scene.position);
}
function animate() {
stats.update();
requestAnimationFrame( animate );
renderer.render( scene, camera );
}
init();
animate();
运行效果如下:
从上可以看到,立方体的宽高基本上都是一样的。
- 剑指offer——面试题10输入一个十进制整数,统计其中二进制1的个数
- 剑指offer——面试题9计算斐波纳切第n个数
- 剑指 offer——面试题8求旋转数组的最小值
- MYSQL INNODB表压缩
- 剑指offer——年龄排序问题
- Mysql Group Replication介绍
- 剑指offer——快速排序
- 架构高性能网站秘笈(四)——反向代理缓存
- 架构高性能网站秘笈(一)——了解衡量网站性能的指标
- MYSQL5.6&5.7编译安装
- 架构高性能网站秘笈(三)——浏览器缓存
- 剑指 offer代码解析——面试题39判断平衡二叉树(高效方法)
- 跟着柴毛毛学Spring(4)——面向切面编程![这里写图片描述](http://img.blog.csdn.net/20171031111402095)
- MYSQL数据闪回方式
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- crontab执行时间与系统时间不一致问题解决
- Linux内核设备驱动之proc文件系统笔记整理
- CentOS7.6系统下使用yum配置lnmp环境的方法
- Linux内核设备驱动之高级字符设备驱动笔记整理
- Linux使用scp命令进行文件远程拷贝详解
- Linux内核设备驱动之Linux内核模块加载机制笔记整理
- linux无损扩容的方法
- Linux内核设备驱动之内核的时间管理笔记整理
- 使用squid搭建http和https的代理服务器设置指南
- linux中gdb的入门使用教程
- Linux命令中Ctrl+z、Ctrl+c和Ctrl+d的区别和使用详解
- Linux lseek函数的使用详解
- Nginx出现500 Internal Server Error 错误的解决方案
- Linux常见基本命令与用法大全
- Navicat 环境测试 innodb 的默认行锁升级表锁