three.js基础API的使用与理解

three项目创建
three+vue3

首先创建vue3的项目:npm create vite@latest

然后通过命令行下载three依赖:

npm install three@0.157.0 -S

注:最好指定版本号,以防止api的不适用

基本使用

在需要用到的组件中按需引入three的对象。

// 引入three.js
import * as THREE from 'three';

我们在实际项目中,光一个THREE对象还是不够的,因此还需要引入其他的对象来辅助我们进行编写。

注意:在老版本时辅助方法路径是three/examples,新版本更换为:three/addons

// 引入扩展库OrbitControls.js
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
// 引入扩展库GLTFLoader.js
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
创建3D场景

想创建一个最基本的3D场景,其实只需要四个因素就可以了。

场景、相机、渲染器、元素。当我们拥有这四个因素后,就可以在页面中创建出一个简单的3D场景

// 引入three.js
import * as THREE from 'three';

// 创建3D场景对象Scene
const scene = new THREE.Scene();

//创建一个长方体几何对象Geometry
const geometry = new THREE.BoxGeometry(100, 100, 100); 
//创建一个材质对象Material
const material = new THREE.MeshBasicMaterial({
    color: 0xff0000,//0xff0000设置材质颜色为红色
}); 
// 网格模型对象Mesh,用户将几何图和材质合并以方便在场景中展示
const mesh = new THREE.Mesh(geometry, material); 
mesh.position.set(0,10,0);
scene.add(mesh); 

let width = 500;
let height = 400;
// 实例化一个透视投影相机对象
const camera = new THREE.PerspectiveCamera(30, width / height, 1, 3000);
// 设置相机在Three.js三维坐标系中的位置
camera.position.set(200, 200, 200); 
//相机观察目标指向Threejs 3D空间中某个位置
camera.lookAt(0, 0, 0); //坐标原点
scene.add(camera)

// 创建渲染器对象
const renderer = new THREE.WebGLRenderer();
//设置three.js渲染区域的尺寸(像素px)
renderer.setSize(width, height); 
renderer.render(scene, camera); //执行渲染操作

// 此时一个简单的3D场景就创建完成了,我们现在只需要将它放在页面元素中就好
document.body.appendChild(renderer.domElment)

下面就来详细介绍下每个API的用法

场景
// 创建3D场景对象Scene
const scene = new THREE.Scene();

这没啥说的,创建一个场景,就好似创建一个舞台。我们可以让各种各样的元素如:人、花草等上去表演。

元素
几何体

在THREE中有好多中定义几何体的API,我们可以直接调用它们来实现绘制。

//BoxGeometry:长方体
const geometry = new THREE.BoxGeometry(100, 100, 100);
// SphereGeometry:球体
const geometry = new THREE.SphereGeometry(50);
// CylinderGeometry:圆柱
const geometry = new THREE.CylinderGeometry(50,50,100);
// PlaneGeometry:矩形平面
const geometry = new THREE.PlaneGeometry(100,50);
// CircleGeometry:圆形平面
const geometry = new THREE.CircleGeometry(50);

更多几何体可以参考官网

材质

有了上面的API调用后,我们现在拥有了一个自定义的几何体图形。但是他的形状可能不如意。所以现在需要使用材质API来为我们定义的材质添砖加瓦。

现在使用一个最基本的材质为矩形盒子添加颜色

//创建一个材质对象Material
const material = new THREE.MeshBasicMaterial({
    color: 0xff0000,//0xff0000设置材质颜色为红色
}); 

对了,在threejs中模式的几何体设置是正面可见,后面学习了相机控件后,我们会发现自己渲染的几何体只能看到正面,拖动到反面就看不到物体了,此时需要在材质中改变一个参数即可。

// THREE.DoubleSide 双面可见
// THREE.FrontSide  正面可见
// THREE.BackSide   背面可见
new THREE.MeshBasicMaterial({
    side: THREE.FrontSide, //默认只有正面可见
});

一开始使用的高级材质有漫反射材质MeshLambertMaterial和高光材质MeshPhongMaterial。

漫反射材质:就是当光源照射到几何体身上时,光不会有固定的反射角将光源反射出去,而是想四方周围反射。

高光材质:就是当光源照射到几何体身上时,光会根据照射的角度来确定一个固定的反射角,由反射角反射出去。高光的地方更加明显,渲染出来的几何体更加逼真。

网络模型

好了,现在几何体和材质都有了,这时需要具体的对象来将他们整合在一起,这里使用网格模型来表示一个虚拟的物体。在最后为这个网格模型位置,将这个网格模型放在我们的相机设置的可视范围内就可以了。

// 网格模型对象Mesh,用户将几何图和材质合并以方便在场景中展示
const mesh = new THREE.Mesh(geometry, material); 
mesh.position.set(0,10,0);
scene.add(mesh); 
相机

PerspectiveCamera:透视投影相机

在three.js中提供了两个相机,分别是PerspectiveCamera透视投影相机、OrthographicCamera正投影相机。透视投影相机的本质就是模拟人眼观察周围环境的规律。

在使用时,需要new THREE.PerspectiveCamera()实例化一个对象,其中PerspectiveCamera类有四个参数。分别是fov, aspect, near, far。相机分别用这四个参数构成一个四棱台,也称为视锥体。只有在视锥体内的元素才能被渲染出来。

  • fov:相机视锥体竖直方向视野角度,一般角度越大,看的面越广。
  • aspect:相机视锥体水平方向和竖直方向长度比,一般设置为Canvas画布宽高比width / height
  • near:相机视锥体近裁截面相对相机距离
  • far:相机视锥体远裁截面相对相机距离,far-near构成了视锥体高度方向

在这里插入图片描述

position

camera.position.set(200, 200, 200):使用代码来控制场景中相机的位置,相机的位置决定了看到物体的角度和大小。就好像人站在远处看高楼,感觉也不怎么高,但是在楼底下就看出楼是非常高了。

lookAt

camera.lookAt(0, 0, 0)这行代码表示往哪个位置拍照,就像人体一样,光有确定位置还不行,就好像你像看正前方的公园,但是在背过身去看背面的高楼,那肯定是看不到你想看的公园的。

注意:如果项目中有使用到相机控件,那个相机控件在初始化时会重置lookAt的值,因此光在这里更改还不行,还要修改相机控件的target值。(下面会说)

渲染器

通过WebGL渲染器WebGLRenderer可以实例化一个WebGL渲染器对象。然后使用setSize(width, height)的方式来设置渲染面的大小,最后通过渲染方法.render()来实现场景的渲染。

不过此时光有渲染器还不行,还需要添加到dom中。使用渲染器的.domElement属性将canvas元素添加到body中,具体使用代码如下:

// 创建渲染器对象
const renderer = new THREE.WebGLRenderer();
//设置three.js渲染区域的尺寸(像素px)
renderer.setSize(width, height); 
renderer.render(scene, camera); //执行渲染操作

// 此时一个简单的3D场景就创建完成了,我们现在只需要将它放在页面元素中就好
document.body.appendChild(renderer.domElment)

通过以上操作可以将场景中的物体都展示到界面上,但是默认情况下,WebGL为了保持性能,会关闭抗锯齿功能。此时我们渲染出来的几何体多多少少会出现点锯齿,很不美观。此时初始化渲染器是设置一个参数即可。

const renderer = new THREE.WebGLRenderer({
  antialias:true, // 默认是false
});
// 或 renderer.antialias = true,

如果在canvas画布上输出时有模糊的问题,可能是你的设备像素比和three默认的像素比不同,导致计算出现覆盖模糊了。这是需要设置下你的像素比。

// 不同硬件设备的屏幕的设备像素比window.devicePixelRatio值可能不同
// window.devicePixelRatio这是window自带的方法参数,不用管直接用即可
renderer.setPixelRatio(window.devicePixelRatio);

有时需要渲染出来的背景颜色是自定义的,那么:

renderer.setClearColor(0x444444, 1); //设置背景颜色
光源

在生活中,如果没有光,我们周围就会一片漆黑,这时什么都看不到。所以THREE中使用Light类来模拟光照。就是模拟光照Light对网格模型Mesh表面的影响。

但是在上面的案例中,我们没有添加光源,但是依然可以看到有物体被渲染出来了,是因为我们使用的材质不同,有些材质是不受光源的影响。但是有些材质为了渲染的更逼真、更贴合实际生活,是需要光源的加入的。
在这里插入图片描述
在THREE中主要的光源有:

  • 点光源:PointLight
  • 环境光:AmbientLight
  • 平行光源:DirectionalLight
  • 聚光源:SpotLight(用得不多)

下面以点光源为例:

//点光源:两个参数分别表示光源颜色和光照强度
// 参数1:0xffffff是纯白光,表示光源颜色
// 参数2:1.0,表示光照强度,可以根据需要调整
const pointLight = new THREE.PointLight(0xffffff, 1.0);

如果你不想再初始化时定义他的光照强度,可以动态在js中定义

pointLight.intensity = 1.0;//光照强度

在生活中光线会随着距离的增加而逐渐减少,我们这里可以设置衰减的程度。

// 设置光源不随距离衰减
pointLight.decay = 0.0;
//或者设置光源随距离衰减
pointLight.decay = 0.1;

定义点光源的位置并添加到场景中

//点光源位置,点光源放在x轴上
pointLight.position.set(400, 0, 0);

//点光源添加到场景中
scene.add(pointLight); 
相机控件

在threejs中的相机控件有很多,主要是用来对场景中的元素进行移动缩放等操作的。使其更有3D立体感。

这里使用轨道控制器OrbitControls相机控件。

// 引入轨道控制器扩展库OrbitControls.js
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';

实例化一个new OrbitControls相机控件时,需要两个参数,一个是需要控制的相机,一个是需要控制的canvas元素。使用的具体方式如下:

// 设置相机控件轨道控制器OrbitControls
const controls = new OrbitControls(camera, renderer.domElement);
controls.target(0,0,0)
// 如果OrbitControls改变了相机参数,重新调用渲染器change事件
controls.addEventListener('change', function () {
    // 注意:如果这里不执行重新渲染操作,系统会只改变参数,而不渲染场景
    renderer.render(scene, camera); 
    console.log('camera.position',camera.position);
});

controls.target(0,0,0)这是指控件的焦点围绕哪个对象进行旋转,因此如果想更改camear.lookAt的属性时,记住一点要设置控件的此target属性,反正自定义的lookAt属性不生效。

其实相机控件OrbitControls的本质就是改变相机的位置,视角等参数,通过观看角度的不同,来达到我们视线观察物体的不同。

辅助线

辅助线主要的作用是在开发中帮助我们确定物体位置的工具。

坐标转辅助线

使用THREE.AxesHelper(x,y,z)来初始化坐标线。分别又三个参数来改变他们的xyz轴的长度。

// AxesHelper:辅助观察的坐标系
const axesHelper = new THREE.AxesHelper(150);
scene.add(axesHelper);

此时,在屏幕上会出现三条线段,分别是红绿蓝三种颜色的线,分别对应xyz轴,

网格辅助线
const axeshelper = new THREE.GridHelper(100);
scene.add(axeshelper)

完结语

这是本人的学习笔记,如果有哪里理解或笔记不正确的地方,请各位朋友多多指教,如果有不懂或技术上的难题也可以私信我,咱们一块研究,共同进步嘛。

  • 25
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值