Threejs 三维开发系列之Threejs基础概念

Threejs 三维开发系列之Threejs基础概念_第1张图片

  • Threejs简介
  • (是什么)Threejs是一个web端的3D图形引擎,能利用js创建和控制各种三维模型和场景
  • (能用来做什么)可以用js开发各种复杂的三维场景、空间模型动画展示、各种三维小游戏(比如微信跳一跳就是Threejs开发)。
  • (优势) 传统三维开发一般是c++ openGl,开发成本大效率低,threejs封装了大量底层图形计算,在js应用层能以很高的效率完成各种三维产品开发。
  • (劣势) 学习曲线比较陡峭,需要掌握一定图形和数学知识,大模型3D场景对设备性能有一定的要求,小型场景问题不大。


基础坐标系概念

  • 不同于常规前端开发只有xy两个坐标系,threejs多了一个z坐标轴,因此开发场景从二维的平面转换为了三维的立体空间,z轴是往屏幕外面朝向
  • Threejs坐标系采用的是右手坐标系

Threejs 三维开发系列之Threejs基础概念_第2张图片

Threejs安装

  • npm模式安装:npm install three
// 方式 1: 导入整个 three.js核心库
import * as THREE from 'three';

const scene = new THREE.Scene();


// 方式 2: 仅导入你所需要的部分
import { Scene } from 'three';

const scene = new Scene();
  • cdn模式安装,由于 three.js 依赖于ES module,因此任何引用它的script标签必须使用type="module"。如下所示:


基础结构搭建

  • html 中 引入canvas组件



渲染器 WebGLRenderer

  • 渲染器是用来将Threejs的各种三维元素,通过canvas展示出来的一种渲染引擎。
  • 设置好渲染器各种参数后,通过调用render方法来进行界面渲染
//先定义渲染器尺寸,下面是浏览器全屏
const size = {
  width: window.innerWidth,
  height: window.innerHeight,
}

//获取canvas Dom元素
const canvas = document.querySelector('canvas.webgl')
//将dom引入传入渲染器,用来创建渲染器
const renderer = new THREE.WebGLRenderer({ canvas })
//设置渲染器尺寸
renderer.setSize(size.width, size.height)
//设置渲染器像素比 避免有些高分辨率的设备把屏幕弄得太模糊,设置像素比最大2X
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))

场景 Scene

  • 场景就是整个三维空间所有虚拟元素容器,有点类似于前端的虚拟Dom
  • 主要常用的方法是 add(),用来给场景添加各种元素
  • 真正让场景生效的是渲染器的render方法会传入场景参数
//创建场景
const scene = new THREE.Scene()

网格对象 Mesh

  • Mesh是一种三维网格对象,也就是放在三维空间种的实物,Mesh由2种东西合成:
    1. Geometry 几何体,用来定义是三维物体的形状大小和网格分段密度,比如BoxGeometry是长方体,可以传入长宽高参数。
    2. Material 附着在几何体上的材质,用来定义颜色、透明度等等
  • 可以通过 mesh.position.set(0,0,0) 用来调整网格对象中心点的坐标
  • 最后把网格对象加入场景中 scene.add(mesh)
//创建mesh模型(由几何体+材质)  正方体
//长宽高为1的立方体 长宽高的线条分段是5条,用来调整网格密度
const geometry = new THREE.BoxGeometry(1, 1, 1, 5, 5, 5)   
const material = new THREE.MeshBasicMaterial({
  color: 0x03c03c, // 材质的颜色
  transparent:true,// 开启透明
  opacity:0.5,// 设置透明度
  wireframe: true, //显示网格虚线
})
const mesh = new THREE.Mesh(geometry, material)
mesh.position.set(0,0,0)
scene.add(mesh)

相机 Camera

  • 横看成岭侧成峰,不同于二维平面,在三维世界中从不角度看同一样东西,会有完全不同的呈现,所以在Threejs中引入Camera的概念,也就是不同的观察视角
  • PerspectiveCamera(fov, aspect, near, far) 相机有四个参数
    • fov 视线观察角度 比如45就是以45度角来观察
    • aspect 渲染器的宽高比
    • near 从多近的距离才开始渲染,就是相机能看到的最近的距离
    • far 最多渲染多远的距离,就是相机能看到的最远的距离

如图所示

Threejs 三维开发系列之Threejs基础概念_第3张图片

//初始化相机 透视相机 
//这里是以45度观察 不设最远最近距离
const camera = new THREE.PerspectiveCamera(45, size.width/size.height)
//相机的位置放在在 x=3 y=3 z=3的位置
camera.position.set(3, 3, 3)
//然后相机看向 x=0 y=0 z=0的位置
camera.lookAt(0, 0, 0)
//场景添加相机
scene.add(camera) 

渲染

已经完成所有场景布置了, 可以调用渲染器的render渲染方法,需要传入参数场景Scene和相机camera

renderer.render(scene, camera)

这个时候就可以看到一个网格立方体了

Threejs 三维开发系列之Threejs基础概念_第4张图片

辅助观察坐标系

但是这种太模糊,没有位置概念,可以引入辅助坐标系,以方便更好观察

Tips:以下代码需要在render渲染调用之前加,render执行过后渲染就完毕了

//添加坐标轴 辅助查看 
const axesHelper = new THREE.AxesHelper(150)
scene.add(axesHelper)

可以看到多了三个线,其中红色的是x轴、绿色是 y轴、蓝色的是z轴,xyz交汇处就是0,0,0原点

Threejs 三维开发系列之Threejs基础概念_第5张图片

动态渲染

目前我们上面看到的渲染是静态渲染,只渲染了一次,可以利用requestAnimationFrame浏览器自带的刷新器,动态的去改变网格对象的参数,达到视线动态渲染旋转的效果

在最后面加上如下代码

// 动态渲染
const tick = () => {
  renderer.render(scene, camera)
  mesh && (mesh.rotation.x += 0.02)     //以x轴旋转
  // mesh && (mesh.rotation.y += 0.02)     //以y轴旋转
  // mesh && (mesh.rotation.z += 0.02)     //以z轴旋转
  window.requestAnimationFrame(tick)
}
tick()

就能看到立方体开始旋转了

Threejs 三维开发系列之Threejs基础概念_第6张图片

调整观察视角

目前相机观察视角是固定的,利用OrbitControls可以利用鼠标或者手势拖拽调整相机的观察视角

//在代码最前面import 轨道控制器
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";

//在渲染前创建轨道控制器 用来用鼠标控制相机
const controls = new OrbitControls(camera, renderer.domElement)
controls.enableDamping = true

// 动态渲染 更新控制器update
const tick = () => {
  renderer.render(scene, camera)
  mesh && (mesh.rotation.x += 0.02)     //以x轴旋转
  // mesh && (mesh.rotation.y += 0.02)     //以y轴旋转
  // mesh && (mesh.rotation.z += 0.02)     //以z轴旋转
  controls.update()  // 更新控制器
  window.requestAnimationFrame(tick)
}
tick()

附 gitte源码: ThreeJsDemo: ThreeJs Demo

你可能感兴趣的:(前端开发,Threejs,三维开发)