简介
本系列教程需要具备threejs的基础入门知识,了场景、几何体、相机等基础概念。
在之前的教程中,我们创建了一系列物体,这些物体都是三维物体。如下图中的地面和蓝色立方体:
在上面的场景中,物体与物体之间是有空间位置可言的,在Three.js中,我们使用三维向量描述物体在场景中的空间信息。
三维向量(3D Vector)是一个非常重要的概念,它被用来表示和操作三维空间中的点。Three.js提供了一系列的类和方法来处理三维向量,其中最基本的就是Vector3 类。
三维物体Object3D
我们打印模型的属性值看一下
可以看到,模型继承一个叫做Object3D的基类。
Object3D表示三维物体,是Three.js中大部分对象的基类,提供了一系列的属性 和方法来对三维空间中的物体进行操纵。
API:threejs.org/docs/?q=OB#...
常用属性
属性名 | 类型 | 属性释义 |
---|---|---|
### castShadow | ### Boolean | 对象是否被渲染到阴影贴图中。默认值为false。 |
### id | Integer | 只读 ------ 表示该对象实例ID的唯一数字。 |
### position | ### Vector3 | 表示对象局部位置的Vector3。默认值为(0, 0, 0)。 |
### receiveShadow | ### Boolean | 材质是否接收阴影。默认值为false。 |
### rotation | ### Euler | 物体的局部旋转,以弧度来表示。(请参阅Euler angles-欧拉角) |
### scale | ### Vector3 | 物体的局部缩放。默认值是Vector3( 1, 1, 1 )。 |
### visible | ### Boolean | 可见性。这个值为true 时,物体将被渲染。默认值为true。 |
这些物体的很多属性我们都使用过,比如给模型设置位置
js
boxMesh.position.set(0, 0.5, 0);
实现模型在光照下的投影
js
// 地面接受光源
floorMesh.receiveShadow = true;
// 物体投射光源
boxMesh.castShadow = true;
物体位置及三维向量(Vector3)
观察Object3D的属性,我们会发现position属性和scale属性度继承自一个叫Vector3的对象。Vector3表示三维向量,描述的就是物体在空间中的位置信息。
它可以表示很多事务:
- 一个位于三维空间中的点。
- 一个在三维空间中的方向与长度的定义。在three.js中,长度总是从(0, 0, 0)到(x, y, z)的 Euclidean distance(欧几里德距离,即直线距离), 方向也是从(0, 0, 0)到(x, y, z)的方向。
- 任意的、有顺序的、三个为一组的数字组合。
构造函数
创建一个新的Vector3:
js
Vector3( x : Float, y : Float, z : Float )
- x - 向量的x值,默认为0。
- y - 向量的y值,默认为0。
- z - 向量的z值,默认为0。
属性
.isVector3 : Boolean
.x : Float
.y : Float
.z : Float
我们看看物体的position属性是不是一个三维向量
使用xyz属性更改模型在空间中的位置
js
boxMesh.position.x = 5;
方法
方法 | 释义 |
---|---|
.set ( x : Float, y : Float, z : Float ) | 设置该向量的x、y 和 z 分量。 |
使用.set 方法设置其空间位置
js
boxMesh.position.set(5, 0.5, 0);
物体的缩放scale
scale也是一个三维向量属性,因此它的方法和position是一样的。
我们将物体整体缩放一倍:
根据之前的代码,我们知道物体的空间坐标是1, 1, 1
js
// 2.2创建一个立方体
const boxMesh = new THREE.Mesh(
new THREE.BoxGeometry(1, 1, 1),
// 使用高光材质
new THREE.MeshPhongMaterial({ color: 0x0099ff, shininess: 800 })
);
因此,想让物体缩放一倍,scale的set属性设置(2,2,2)即可
js
boxMesh.scale.set(2, 2, 2);
物体的旋转与欧拉角
物体的旋转属性rotation方法继承自Euler对象。
欧拉角描述一个旋转变换,通过指定轴顺序和其各个轴向上的指定旋转角度来旋转一个物体。
对 Euler 实例进行遍历将按相应的顺序生成它的分量 (x, y, z, order)。
属性与方法:
属性名 | 类型 | 释义 |
---|---|---|
### isEuler | Boolean | |
### x | Float | 当前x分量的值。 |
### y | Float | 当前y分量的值。 |
### z | Float | 当前z分量的值。 |
方法 | ||
### set | ( x : Float, y : Float, z : Float, order : String ) | x 用弧度表示x轴旋转量。order表示旋转顺序的字符串。 |
我们沿着Z轴将物体进行旋转
ini
boxMesh.rotation.y = Math.PI / 1 / 4;
物体的显示隐藏
js
boxMesh.visible = false;
常用方法
方法 | 属性释义 |
---|---|
.lookAt ( vector : Vector3 ) : undefined | |
.rotateX ( rad : Float ) | 绕局部空间的X轴旋转这个物体。 |
translateX | 沿着X轴将平移distance个单位。 |
物体的平移
js
boxMesh.translateX(4);
物体的组合
对于一个三维物体Object3D,我们可以使用组(Group)来实现多个物体的组合。
Group的使用方法非常简单
js
// 创建一个组
const group = new THREE.Group();
// 创建立方体1
const boxMesh1 = new THREE.Mesh(
new THREE.BoxGeometry(1, 1, 1),
);
// 创建立方体2
const boxMesh2 = new THREE.Mesh(
new THREE.BoxGeometry(1, 1, 1),
);
// 设置立方体位置
boxMesh1.position.set(0, 0.5, 0);
boxMesh2.position.set(0, 2.5, 0);
// 向组中添加几何体
group.add(boxMesh1);
group.add(boxMesh2);
// 将几何体挂载在场景中
scene.add(group);
注意,组合后的物体类似于一个整体,进行移动和缩放时,会整体生效。