先运行一段threejs代码,然后再分析。
代码如下:
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover" />
<meta name="format-detection" content="telephone=no">
<title>three.js</title>
<script src="./three.min.js"></script>
</head>
<body>
<script>
// 画布的宽度
var cw = 500, ch = 500;
// 1. 建立一个场景
var scene = new THREE.Scene();
// 2. 设立相机
var camera = new THREE.PerspectiveCamera( 75, cw / ch, 0.1, 1000 );
camera.position.z = 5;
// 3. 准备渲染器
var renderer = new THREE.WebGLRenderer();
renderer.setSize( cw, ch );
document.body.appendChild( renderer.domElement );
// 4. 演员准备好
var geometry = new THREE.BoxGeometry( 1, 1, 1 );
var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
var cube = new THREE.Mesh( geometry, material );
// 4.1 演员就位
scene.add( cube );
// 5. 开始表演(渲染)
//renderer.render( scene, camera );
// 动画
let timer = null;
function render() {
if (timer) {
clearTimeout(timer);
timer = null;
}
cube.rotation.x += 0.1;
cube.rotation.y += 0.1;
renderer.render( scene, camera );
//requestAnimationFrame( render );
timer = setTimeout(render,100);
}
render();
</script>
</body>
</html>
对上面的代码进行分析
Three.js使用的是面向对象的方式来构建程序,包含3个基本对象: 场景(scene), 相机(camera), 以及一个渲染器(renderer)。
拿电影来类比的话,场景对应于整个布景空间,相机是拍摄镜头,渲染器用来把拍摄好的场景转换成胶卷(对于网页来讲,是电脑屏幕)。 场景和相机代表了3D观察空间和数据模型,渲染器则包含了WebGL绘图上下文和着色器。
第一步,建立一个场景,这个比较好理解。
var scene = new THREE.Scene();
场景是所有物体的容器,可以理解为canvas画布。
第二步,设立一台相机,这里用的是最常见的远景相机(PerspectiveCamera),或者称为透视投影照相机,它类似于人眼观察的方式。
除了远景相机(透视投影照相机)还有其他很多种相机,平常用的不多,稍后涉及。
var camera = new THREE.PerspectiveCamera( 75, cw / ch, 0.1, 1000 );
PerspectiveCamera( fov : Number, aspect : Number, near : Number, far : Number )
PerspectiveCamera是Camera抽象类的一个子类,它的四个参数见下面的图:
如上图,这四个参数一起定义了摄像机的[viewing frustum](视锥体)。
fov是视角(field of view),即视景体竖直方向上的张角(是角度制而非弧度制),如侧视图所示。
aspect是相机拍摄面的长宽比(aspect ratio),即照相机水平方向和竖直方向长度的比值,通常设为Canvas的横纵比例。我们几乎总是会使用元素的宽除以高,否则会出现挤压变形。
near和far是近裁剪面(near clipping plane)和 远裁剪面(far clipping plane),即照相机到视景体最近、最远的距离,均为正值,且far应大于near。
透视图中,灰色的部分是视景体,即near平面和far平面之间的矩形体,是可能被渲染的物体所在的区域,超出这个范围,物体时渲染不出来的。
第三步,准备渲染器,也比较好理解。
var renderer = new THREE.WebGLRenderer();
除了我们这里使用的WebGLRenderer,three.js还支持一些其它渲染器,基本上只是用来回退处理那些不支持WebGL的旧式用户浏览器。
除了创建renderer实例,我们还需要设置渲染空间的尺寸,一般就使用目标canvas的宽高(cw和ch),也可以给定一个小尺寸。
如果你想保持渲染空间的尺寸,但使用一个较低的分辨率,你可以在调用setSize的时候设置参数updateStyle为false,比如 setSize(cw/2, ch/2, false) 将使用1/2分辨率来绘制你的应用程序,假定<canvas>为100%的宽高。
最后,我们把 renderer 元素添加到HTML文档中。这里是一个 <canvas> 元素,渲染器用来显示场景。
第四步,演员做好准备
var geometry = new THREE.BoxGeometry( 1, 1, 1 );
var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
var cube = new THREE.Mesh( geometry, material );
scene.add( cube );
我们使用盒子模型(BoxGeometry),这是一个包含立方体所有顶点和填充面的对象。
除了这个几何模型(geometry)外,我们还需要一个材料(material)来对其着色。Three.js支持多种材料,现在我们只使用 网孔基础材料(MeshBasicMaterial)。 所有材料都含有一个属性对象。这里简单起见,我们只提供了颜色值为0x00ff00,表示绿色。这和CSS和Photoshop中16进制颜色值一样。
还有就是我们需要一个网孔(Mesh)。网孔是用来承载几何模型的一个对象,还可以把材料应用到它上面,然后添加到场景中。
默认情况下,当我们调用 scene.add() 时,对象将被添加到原点处,即坐标点(0,0,0)。
第五步,渲染
renderer.render( scene, camera );
页面会渲染出一个绿色的矩形,看不出3D效果,所以代码里面用来动画,让立方体旋转起来,由于requestAnimationFrame动画旋转太快,所以用setTimeout改写了一下,让立方体旋转的慢一点。
参考资料: