
概述:基于WebGL的三维引擎,目前是国内资料最多、使用最广泛的三维引擎,可以制作一些3D可视化项目

目前随着元宇宙概念的爆火,THREE技术已经深入到了物联网、VR、游戏、数据可视化等多个平台。
最近一段时间主要对之前学习three.js的总结和记录,记录只对自己觉得重要的部分记录,其他的可以参考别的平台资源。

目前作品的相关展示平台已上线:VR_Team作品展示平台,欢迎大家查看。
项目开源地址:web3d-product,下面为一部分的网页的作品展示。

在线预览:粒子平面墙

在线预览:迷失太空

在线预览:粒子海浪

在线预览:银河系

在线预览:漫画-蜘蛛侠

在线预览:电脑主机拆解

在线预览:后期处理-虚幻花朵

功能说明
public文件夹:存放一些独立的案例界面(html格式),不需要依赖,可以直接运行在网页 assets存在依赖的资源Basic:基础界面Comic:二维漫画Particles:粒子效果Processing:后期chuliVisualization:可视化srcviews:功能主界面//安装依赖 npm i //运行项目 npm run dev  
该模板集成最简单的一个three.js环境,在此基础上可以自行搭建。
前端:vue + three.js + js

概述:本质就是在render()函数不断渲染的过程中调用动画,每一帧不断增加目标体的位置,以此循环
体验地址:基础动画
// 时间动画 let clockAnimate=()=>{ const elapsedTime=clock.getElapsedTime()  cube.position.x = Math.cos(elapsedTime) cube.position.y=Math.sin(elapsedTime) }  https://github.com/greensock/GSAP
// gasp动画 let gsapAnimate=()=>{ 	gsap.to(cube.position, { x: 5, duration: 3, delay:1}) }  
| 参数(属性) | 含义 | 
|---|---|
| left | 渲染空间的左边界 | 
| right | 渲染空间的右边界 | 
| top | 渲染空间的上边界 | 
| bottom | 渲染空间的下边界 | 
| near | near属性表示的是从距离相机多远的位置开始渲染,一般情况会设置一个很小的值。 默认值0.1 | 
| far | far属性表示的是距离相机多远的位置截止渲染,如果设置的值偏小小,会有部分场景看不到。 默认值1000 | 
let width = window.innerWidth; let height = window.innerHeight; const camera = new THREE.OrthographicCamera(width / - 2, width / 2, height / 2, height / - 2, 1, 1000); scene.add(camera); camera.position.set(100, 200, 100);  
| 参数 | 含义 | 默认值 | 
|---|---|---|
| fov | fov表示视场,所谓视场就是能够看到的角度范围,人的眼睛大约能够看到180度的视场,视角大小设置要根据具体应用,一般游戏会设置60~90度 | 45 | 
| aspect | aspect表示渲染窗口的长宽比,如果一个网页上只有一个全屏的canvas画布且画布上只有一个窗口,那么aspect的值就是网页窗口客户区的宽高比 | window.innerWidth/window.innerHeight | 
| near | near属性表示的是从距离相机多远的位置开始渲染,一般情况会设置一个很小的值。 | 0.1 | 
| far | far属性表示的是距离相机多远的位置截止渲染,如果设置的值偏小,会有部分场景看不到 | 1000 | 
let width = window.innerWidth; let height = window.innerHeight; const camera = new THREE.PerspectiveCamera(45, width / height, 1, 1000); camera.position.set(150, 100, 300); camera.lookAt(scene.position);  注意
fov视口是上下的,不是左右概述:通过鼠标控制相机的移动、旋转、缩放以此实现场景物体的控制
导包
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'  应用
const controls = new OrbitControls(camera, renderer.domElement)  自旋转

controls.autoRotate = true  必须在render函数调用update实时更新才奏效

像素比:将一个像素分成若干个n*n的像素,这样的话显示会更加清晰,一般来说像素比为2就够了
// 自适应屏幕 let onWindowsResize = () => {      sizes.width = window.innerWidth     sizes.height = window.innerHeight     camera.aspect = sizes.width / sizes.height     camera.updateProjectionMatrix()     renderer.setSize(sizes.width, sizes.height)     renderer.setPixelRatio(window.devicePixelRatio) }  //双击全屏 let onWindowsScreen = () => {     let isFullScreen = document.fullscreenElement     if (!isFullScreen) {     	renderer.domElement.requestFullscreen()     } else {     	document.exitFullscreen()     } } let expandFunction = () => {     window.addEventListener('resize', onWindowsResize)     window.addEventListener('dblclick', onWindowsScreen) }  
概述:几何体由一个个顶点粒子构成,每个粒子包含了位置、uv贴图(3d=>2d坐标对应)等,三个顶点形成一个面,在three.js中。物体由一个个三角形面构成。
BufferGeometry:是面片、线或点几何体的有效表述。包括顶点位置,面片索引、法相量、颜色值、UV 坐标和自定义缓存属性值。使用 BufferGeometry 可以有效减少向 GPU 传输上述数据所需的开销。目前,three.js的物体都用上了Buffer,可以直接调用,一些顶点可以使用这个。

演示链接:三角形
let createBufferTriangle = () => {     const count = 50     for (let i = 0; i < count; i++) {         const pointsArray = new Float32Array(9)         for (let j = 0; j < 9; j++) {             pointsArray[j] = (Math.random() - 0.5) * 5         }          const geometry = new THREE.BufferGeometry()         const material = new THREE.MeshBasicMaterial({             color: new THREE.Color(                 Math.random(),                 Math.random(),                 Math.random(),             ),             opacity: Math.random(),             transparent: true,             // wireframe:true         })         geometry.setAttribute('position', new THREE.BufferAttribute(pointsArray, 3))         // geometry.attributes.position = new THREE.BufferAttribute(pointsArray, 3)         const triangle = new THREE.Mesh(geometry, material)         scene.add(triangle)      } }    dat.gui:https://github.com/dataarts/dat.gui 样式好看,动画有点不流畅
lil-gui:https://lil-gui.georgealways.com/ 动画流畅,官方案例用的多
mip映射(mipmapping)是一种技术,它包括一次又一次地创建半个较小版本的纹理,直到得到1x1纹理。
 所有这些纹理变化都会发送到GPU,GPU将自动选择最合适的纹理版本。所有的这些都已经由THREE.js和GPU处理,但是我们可以选择不同的过滤算法

概述:原本的贴图大小大于要渲染的大小,如缩放物体,应用这个

概述:原本的贴图大小小于要渲染的大小,如缩放物体,应用这个

当纹理的minFilter属性使用NearestFilter时,我们可以不需要再mip映射了,可以通过以下代码为纹理停用mipmapping,使得GPU不再处理mip映射
//如果不在乎远处物品效果如失真之类的,纹理的minFilter属性使用 NearestFilter时可以停用mipmapping以获得更好性能,根据实际项目而定 colorTexture.generateMipmaps = false  参考链接:https://threejs.org/docs/index.html#api/zh/constants/Textures
参考链接:https://blog.csdn.net/weixin_43990650/article/details/121595334
参考链接:https://www.bilibili.com/read/cv15999592
掘金:https://juejin.cn/post/7101209181822124069
这部分可以参考网上的资料,这里不做过多讲解
https://blog.csdn.net/weixin_43990650/article/details/121595334
四步走
灯光cast=>球体cast=>平面receive=>renderer设置

概述:灯光利用照相机渲染出shadow map贴到场景中,得到阴影
简单例子
//直射光 const directionalLight = new THREE.DirectionalLight(0xffffff, 0.5) scene.add(directionalLight)  directionalLight.position.set(2, 2, -1) directionalLight.castShadow = true directionalLight.shadow.mapSize.width = 1024 directionalLight.shadow.mapSize.height = 1024 directionalLight.shadow.camera.near = 1 directionalLight.shadow.camera.far = 6 directionalLight.shadow.camera.top = 2 directionalLight.shadow.camera.right = 2 directionalLight.shadow.camera.bottom = - 2 directionalLight.shadow.camera.left = - 2  directionalLight.shadow.radius = 10  //只是实体化的工具,参数修改上面的 const directionalLightCameraHelper = new THREE.CameraHelper(directionalLight.shadow.camera) scene.add(directionalLightCameraHelper) directionalLightCameraHelper.visible = false  注意:

概述:提前在blender渲染好阴影,这个不会变化,关闭渲染器阴影投射就行

概述:在小球下面放置具有阴影贴图的平面,关闭渲染器阴影,跟随小球运动改变透明度
renderer.shadowMap.enabled = false  概述:粒子可以被用来创建星星、烟雾、雨滴、灰尘、火焰等等。我们可以使用合理的帧速率来创建数千个粒子。每个粒子都是由始终面向摄影机的平面(俩个三角形)组成的
参考链接:https://blog.csdn.net/weixin_43990650/article/details/121736698
101801718.png" alt=“6” style=“zoom:50%;” />
概述:提前在blender渲染好阴影,这个不会变化,关闭渲染器阴影投射就行

概述:在小球下面放置具有阴影贴图的平面,关闭渲染器阴影,跟随小球运动改变透明度
renderer.shadowMap.enabled = false  概述:粒子可以被用来创建星星、烟雾、雨滴、灰尘、火焰等等。我们可以使用合理的帧速率来创建数千个粒子。每个粒子都是由始终面向摄影机的平面(俩个三角形)组成的

本项目由`江苏海洋大学计算机工程学院VR_Team106完成,欢迎加入!!!