threejs教程-三维物体与三维向量

简介

本系列教程需要具备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 ) 设置该向量的xyz 分量。

使用.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);

注意,组合后的物体类似于一个整体,进行移动和缩放时,会整体生效。

相关推荐
尘世中一位迷途小书童几秒前
前端工程化基石:package.json 40+ 字段逐一拆解
前端·javascript·架构
OpenTiny社区7 分钟前
WebMCP + WebSkills:企业级智能化页面操控方案,兼顾隐私安全与高效落地!
前端·ai编程·mcp
酉鬼女又兒12 分钟前
零基础快速入门前端JavaScript四大核心内置对象:Math、Date、String、Array全解析(可用于备赛蓝桥杯Web应用开发)
前端·javascript·css·蓝桥杯·前端框架·js
__sgf__17 分钟前
ES11(ES2020)新特性
前端·javascript
__sgf__31 分钟前
ES8(ES2017)新特性
前端·javascript
__sgf__34 分钟前
ES9(ES2018)新特性
前端·javascript
送鱼的老默40 分钟前
学习笔记--vue3 watchEffect监听的各种姿势用法和总结
前端·vue.js
你挚爱的强哥40 分钟前
解决:动态文本和背景色一致导致文字看不清楚,用js获取背景图片主色调,并获取对比度最大的hex色值给文字
前端·javascript·github
用户69371750013841 小时前
Android 手机终于能当电脑用了
android·前端
wooyoo1 小时前
花了一周 vibe 了一个 OpenClaw 的 Agent 市场,聊聊过程中踩的坑
前端·后端·agent