引言
Three.js是一款功能强大的JavaScript库,专为在Web浏览器中创建和显示3D图形而设计。它简化了WebGL的复杂性,使开发者能够轻松构建引人入胜的3D动画、模型和交互场景,无需深入了解底层的图形编程细节。
搭建开发环境
学习Three.js最简单的方式当然是创建一个html文件,然后引入Three.js,接着在<script></script>里面开始写就行。但是既然大家来学习Three.js了,估计大多不会真的就这样去使用,而是需要将其结合到Vue或者React项目中。因此我准备一步到位,直接在Vue中进行这篇教程的内容!
首先让我们来顺手创建一个vue项目,我这里选的是vue3+vite(要用就用新的嘛)
npm create vue@latest
npm install
npm run dev
安装Three.js依赖
npm install three --save
基础知识概览
在Three.js的世界里,有几个很重要的概念,分别是:场景(Scene)、相机(Camera)、渲染器(Renderer)、几何体(Geometry)、材质(Material)和光源(Light)。
场景(Scene)
场景是一个三维的世界,在这个世界中可以放置各种各样的物体。它相当于一个容器,用于包含和组织3D对象、光源、相机等元素,共同构成一个完整的3D空间
相机(Camera)
相机是三维空间的观察者,通过相机来查看场景。在Three.js中,相机决定了视角和视野范围,是连接3D场景和观察者之间的桥梁。Three.js支持多种相机类型,如透视投影相机和正投影相机,分别用于模拟人眼视角和平行投影视角
渲染器(Renderer)
渲染器负责将场景中的3D对象转换为2D图像,然后显示在屏幕上。它是连接Three.js场景和浏览器窗口之间的桥梁,负责处理3D对象的渲染、光照、阴影、材质等方面的细节。Three.js内置了多种渲染器,如WebGLRenderer、CSS3DRenderer等,以适应不同的场景和需求
几何体(Geometry)
几何体是描述三维对象形状的基本构建块,它定义了物体的几何结构,包括顶点、面和其它几何属性。在Three.js中,可以使用内置的几何体类型,如立方体、球体、圆柱体等,或者通过定义顶点和面来自定义几何体形状
材质(Material)
材质定义了物体表面的外观,决定了物体的颜色、纹理、光滑度、透明度等特性。在Three.js中,材质可以看作是场景中物体的皮肤,通过为几何体添加材质,可以使其具有更加逼真的外观效果。Three.js提供了多种材质类型,如基础材质、标准材质、Lambert材质等,以满足不同场景的需求
光源(Light)
光源是模拟3D场景中光照效果的元素,对于渲染真实感的3D场景至关重要。Three.js提供了多种光源类型,如环境光、点光源、聚光灯光源、方向光等,用于模拟不同的光照效果。通过合理设置光源的位置、颜色和强度等参数,可以创建出逼真的光影效果,增强场景的立体感和真实感
上面引用的概念介绍比较官方,其实这些很好理解,说通俗点就是创建一个3D模型得有一个容器吧,不然没地儿放,这个容器就是场景;把模型放到容器里面之后得想办法看到,所以得有个相机;这模型是3D的怎么放到2D屏幕上去呢?这就得用渲染器;这模型总得有个形状吧,所以得有几何体;我希望这模型是亮面的或者哑光的,这就是材质;最后这场景乌漆嘛黑,啥也看不见,那就得加光源了。
创建一个3D场景
首先导入Three.js
import * as THREE from 'three'
创建场景
const scene = new THREE.Scene()
创建相机
//这里的innerWidth和innerHeight可以换成具体的宽度与高度值
const camera = new THREE.PerspectiveCamera(45, innerWidth / innerHeight, 0.1, 3000)
// 设置相机位置,参数为三维坐标系的x,y,z坐标
camera.position.set(200, 200, 200)
// 设置相机朝向,参数为三维坐标系的x,y,z坐标
camera.lookAt(0, 0, 0)
创建相机的参数分别为视野角度(fov)、长宽比(aspect)、近截面距离(near)、远截面距离(far)
| 参数 | 含义 |
|---|---|
| fov | 相机视锥体竖直方向视野角度 |
| aspect | 相机视锥体水平方向和竖直方向长度比,一般设置为Canvas画布宽高比width / height |
| near | 相机视锥体近裁截面相对相机距离 |
| far | 相机视锥体远裁截面相对相机距离,far-near构成了视锥体高度方向 |
创建渲染器
const renderer = new THREE.WebGLRenderer()
//设置渲染器尺寸
renderer.setSize(innerWidth, innerHeight)
以上我们就完成了最简单的3D场景搭建,此时可以通过渲染器的render方法渲染出3D场景看看效果。渲染器执行render方法后会生成一个Canvas画布,通过自身的domElement可以拿到这个Canvas画布,并且插入到页面的任意HTML元素上(vue中如果插入到页面失败,可能是因为页面还没挂载,需要在onMounted或者nextTick内执行插入)
//渲染Canvas画布,将场景和相机作为参数传入
renderer.render(scene, camera)
//将渲染出来的Canvas画布插入到body中
document.body.appendChild(renderer.domElement)
创建模型
此时可以看到页面上还是黑漆漆的一片,什么也没有,这是因为目前还只创建了场景,没有创建任何模型,事不宜迟,直接创建一个(在渲染器渲染前创建)
//创建一个长方体几何体(传入参数为长、宽、高)
const geometry = new THREE.BoxGeometry(100, 100, 100)
//创建一个材质
const material = new THREE.MeshBasicMaterial({
color: 0xff0000,
})
//创建模型对象,将几何体与材质作为参数传入
const mesh = new THREE.Mesh(geometry, material)
// 通过scene身上的add方法将模型添加到场景中
scene.add(mesh)
此时保存之后运行,就可以在页面上看到一个红色的正方体了(如下)
但是这时候还看不太出来是3D的,怎样让3D感受更真切一点呢,我们可以加一个轨道控制器,这样我们就可以通过鼠标来对3D场景进行旋转、平移和缩放操作
// 引入轨道控制器(OrbitControls)
import { OrbitControls } from 'three/addons/controls/OrbitControls.js'
// 创建轨道控制器(将相机与domElement作为参数传入)
const controls = new OrbitControls(camera, renderer.domElement)
// 监听轨道控制器的改变,并在改变后重新渲染
controls.addEventListener('change', (e) => {
renderer.render(scene, camera)
})
现在就可以在页面上通过鼠标来操作了,是不是瞬间就有内味儿了。至此已经完成了第一个3D场景的创建,Three.js的知识特别多,后面有空会继续更新这系列文章。最后附上完整代码与源码地址,顺便贴上Three.js的官网和中文教程网站地址,供大家学习
源码地址:https://gitee.com/zhang-lei1027/three-study.git
完整代码
<template>
<div id="threeBox"></div>
</template>
<script setup>
import { onMounted } from 'vue'
// 引入Three.js
import * as THREE from 'three'
// 引入轨道控制器
import { OrbitControls } from 'three/addons/controls/OrbitControls.js'
// 定义宽度和高度
const width = innerWidth
const height = innerHeight
// 创建场景
const scene = new THREE.Scene()
// 创建相机
const camera = new THREE.PerspectiveCamera(45, width / height, 0.1, 3000)
// 设置相机位置
camera.position.set(200, 200, 200)
// 设置相机朝向
camera.lookAt(0, 0, 0)
// 创建渲染器
const renderer = new THREE.WebGLRenderer()
// 设置渲染器尺寸
renderer.setSize(width, height)
//创建一个长方体几何体
const geometry = new THREE.BoxGeometry(100, 100, 100)
//创建一个材质
const material = new THREE.MeshBasicMaterial({
color: 0xff0000,
})
//创建模型对象,将几何体与材质作为参数传入
const mesh = new THREE.Mesh(geometry, material)
// 将模型添加到场景中
scene.add(mesh)
// 创建轨道控制器
const controls = new OrbitControls(camera, renderer.domElement)
// 监听轨道控制器的改变,并在改变后重新渲染
controls.addEventListener('change', (e) => {
renderer.render(scene, camera)
})
// 渲染Canvas画布,将场景和相机作为参数传入
renderer.render(scene, camera)
// 页面挂载完毕后将domElement插入到页面元素内
onMounted(() => {
document.getElementById('threeBox').appendChild(renderer.domElement)
})
</script>
<style scoped>
#threeBox {
width: 100%;
height: 100%;
}
</style>