前言
Three.js ( Javascript 3D library ) 是基于原生WebGL封装运行的三维引擎,WebGL可以看成是浏览器给我们提供的接口,在JavaScript中可以直接用这些API进行3D图形的绘制;而Three.js它封装了诸如场景、灯光、阴影、材质、贴图、空间运算等一系列功能,让你不必要再从底层WebGL开始写起。 Three.js是通过对WebGL接口的封装与简化而形成的一个易用的图形库。
Three.js开发3D应用,通常包括渲染器(Renderer)、场景(Scene)、照相机(Camera),以及在场景中创建的物体,光照等。
一、threejs的安装
1、NPM的安装
npm install --save three
2、组件内使用
import * as THREE from "three";
二、场景
1、场景(scene)介绍
它相当于一个容器,在3d场景中要展现的所有物体、灯光、摄像机等都必须添加到这个容器里面。
2、创建场景对象Scene
Var scene = new THREE.Scene();
3、设置场景的背景色
scene.background = new THREE.Color("#F7F7F7");
三、相机
在threejs中提供了一系列的相机,其中最常用到的是 PerspectiveCamera(透视相机) 和 OrthographicCamera(正交投影相机),它们之间的区别在于透视相机在观察场景中的物体时,呈现出来的物体近大远小,最接近自然的视图。正交投影相机无论从哪个角度观察物体,大小都是一样的。
1、PerspectiveCamera创建, 确定视野范围
let camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
参数说明:
fov: 视场;垂直方向的观察角度,也就是眼睛上下俯视的观察角度。
aspect: (长宽比)是照相机水平方向和竖直方向长度的比值。
near: (近面距离)相机到视景体最近的距离。
far: (远面距离)相机到视景体最远的距离。
2、确定相机的位置
this.camera.position.set(0, 10, 20);
3、操作相机
在很多场景下,我们需要移动相机来观察物体的各个角度,这时需要相机操作控件来控制相机的位置。常用的控制器有:OrbitControls(轨道控制器)、TrackballControls(轨迹球控制器)
OrbitControls:可以使用鼠标控制场景中的对象围绕场景中心旋转和平移
TrackballControls:可以使用鼠标(或控制球)来轻松移动、平移和缩放场景
Pointerlockcontrols:第一人称控制器,以第一人称视角观察室内场景
1)添加控制器
controls = new OrbitControls(camera, canvas);
2)设置控制器聚焦点
controls.target.set(0, 5, 0);
四、光照
在场景中,如果没有光源,那所有的物体都将看不见。最常用的几种光源是AmbientLight、PointLight、SpotLight、DirectionalLight。
AmbientLight:环境光;全局均匀地照亮场景中的所有对象。
PointLight:点光源;从空间中的一点向所有方向发射光线。
SpotLight:聚光源;投射出的是类似圆锥形的光线。
DirectionalLight:平行光;比如太阳光。
例:
{
const color = 0xf1f1f1; //光的颜色
const intensity = 1; //光的强度
const light = new THREE.DirectionalLight(color, intensity);
light.castShadow = true; //开启castShadow生成动态的投影
light.position.set(10, 300, 20);//设置灯光的位置
this.scene.add(light);//将灯光添加到场景中
}
五、渲染器
渲染器决定了渲染的结果应该画在页面的什么元素上面,首先在需要渲染的位置添加页面元素
<canvas id="con"></canvas>
1、渲染器创建
WebGLRenderer:WebGL渲染器使用WebGL来绘制场景(如果设备支持),使用WebGL能够利用GPU硬件加速从而提高渲染性能。
const canvas = document.querySelector("#con");
var renderer = new THREE.WebGLRenderer({
canvas,
antialias: true, //默认为false。是否开启反锯齿
alpha: true, //默认为false。是否可以设置背景色透明
});
2、开始渲染
this.renderer.render(scene, camera);
scene:前面定义的场景。
camera:前面定义的相。
3、domElement属性-canvas对象
const canvas = this.renderer.domElement;
4、循环渲染
requestAnimationFrame(this.render);
requestAnimationFrame(render):这个函数就是让浏览器去执行一次参数中的函数,这样通过上面render中调用requestAnimationFrame()函数,requestAnimationFrame()函数又让rander()再执行一次,就形成了循环渲染。
六、模型添加
3D模型的格式有很多种类可供选择,但每一种格式都具有不同的目的、用途以及复杂性,常用的模型有obj、gltf等等;
OBJ:是一种文本格式存储的模型文件格式,只能存储静态模型;
gltf: 以JSON(.gltf)或二进制(.glb)格式提供模型数据;glTF资源可以传递一个或多个场景,包括网格,材质,纹理,外观等等。
1、引入gltf模型加载器
import GLTFLoader from "three/examples/js/loaders/GLTFLoader";
2、实例化加载器并添加到场景中
const gltfLoader = new GLTFLoader(); //实例化加载器
gltfLoader.load("../../../../static/gltf/zoom/waibucj.gltf", gltf => {
const root = gltf.scene;
root.castShadow = true; // 投影
root.traverse(
function(child) {
if (child.isMesh) {
//设置mesh的一些属性
child.material.metalness = 0.8; //金属度
child.material.roughness = 0.3; //粗糙度
}
},
undefined,
function(error) {
console.error(error);
}
);
this.scene.add(root); //将该模型添加到场景中
});
}
七、环境贴图
在threejs中环境贴图就是利用三维来模拟周边的环境,它通过HDR图像来实现;
1、引入RGBELoader加载器
import { RGBELoader } from "three/examples/jsm/loaders/RGBELoader";
2、如何加载hdr环境贴图
//加载hdr
{
var that = this;
// 使用hdr作为背景色
var pmremGenerator = new THREE.PMREMGenerator(this.renderer);
pmremGenerator.compileEquirectangularShader();//阴影
new RGBELoader()
.setDataType(THREE.UnsignedByteType)
.load("../../../../static/gltf/env4.hdr", texture => {
const envMap = pmremGenerator.fromEquirectangular(texture).texture;
this.scene.environment = envMap; // 给场景添加环境光效果
//this.scene.background = envMap;// 给场景添加背景图
pmremGenerator.dispose();
});
}
八、交互
在物联网项目中,所有三维物体与鼠标交互样式采用的是动态收缩变化的点,此方法弊端是有多少个交互位置就需要创建多少个动态点;
1、动态点实现方式
要实现效果图

a) 创建一个三维物体对象
this.obj = new THREE.Object3D();
b) 创建两个圆的物体
1)外部透明的圆
const geometry = new THREE.CylinderGeometry(8, 8, 0.2, 40, 40); //形状
const material = new THREE.MeshPhongMaterial({
color: 0x01cd88, //物体颜色
opacity: 0.15, //物体透明度
transparent: true
}); //物体材质
const cube = new THREE.Mesh(geometry, material); //创建网格物体
2)内部的圆
const geometry1 = new THREE.CylinderGeometry(4, 4, 1, 40, 40);
const material1 = new THREE.MeshPhongMaterial({
color: 0x01cd88
});
const cube1 = new THREE.Mesh(geometry1, material1);
3)将内部和外部圆组合在一起,添加到第一步创建的三维物体对象,并设置位置添加到场景
this.obj.add(cube);
this.obj.add(cube1);
this.obj.position.set(-220, 192, 121); //设置物体位置
this.scene.add(this.obj); //添加到场景中
4)动画效果添加(此方法执行放在render方法中,它才会一直被执行)
//气泡框动画
BubbleAnimation: function() {
var rot = 0;
if (this.mark == 1) {
const speed = 1 - 1 * 0.1;
rot = 0.006 * speed;
if (this.obj.scale.x <= 1) {
this.mark = 0;
}
this.obj.scale.x -= rot;
this.obj.scale.y -= rot;
} else {
const speed = 1 + 1 * 0.1;
rot = 0.006 * speed;
if (this.obj.scale.x > 1.4) {
this.mark = 1;
}
this.obj.scale.x += rot;
this.obj.scale.y += rot;
}
this.obj.lookAt(this.camera.position);//使物体始终朝向摄像机
}
九、遇到过问题
问题一:模型加载到场景中是黑色的
解决办法:
1)检查是否是模型本身导出问题。可用在线查看器查看导出的模型(https://gltf-viewer.donmccurdy.com/)
2)添加环境贴图
本文介绍了如何在Vue项目中使用Three.js创建3D场景、设置相机、渲染器、添加gltf模型和环境贴图,以及实现交互功能。内容涵盖了Three.js的安装、场景、相机类型、光照、渲染过程、模型导入和环境映射,还讨论了解决模型显示为黑色的问题。
361

被折叠的 条评论
为什么被折叠?



