一、前言
随着Web的快速发展,网页的表现能力愈发强大,人们可以在网页做出很多复杂、精美的动画。渐渐的,人们已经不满足于平面的精美,Three.js应运而生。
Three.js可以简单理解为Three+Js,它是一个3D javascript库,基于WebGL(一种js API)。
二、安装
在这里我们使用npm进行依赖安装
npm install three
由于我们使用的是typeScript,所以我们可能还需要安装它的类型,方便我们对类型定义
npm install @types/three
三、四个重要的条件
-
scene场景:场景就是构造出来装模型的容器
-
renderer渲染器:渲染器就是将我们定义的一个个对象渲染到场景当中
-
camera相机:Three.js其实可以看做是拍照的过程:我们拿着相机对物体(object)进行拍照(renderer)。我们作为“摄像师”当然是看不见相机的,场景中物体的转动,其实是相机的位置在发生变化而不是物体在动。
-
object对象:几何体、模型、粒子、灯光等都是一个个对象
四、制作简单场景
Three.js中的各种类以及其属性可参考:Three.js文档
0、准备
我们需要给生成的canvas准备一个容器
<template>
<div id="three"></div>
</template>
1、引入
//引入threejs
import * as THREE from 'three'
//引入轨道控制器(用来通过鼠标事件控制模型旋转、缩放、移动),没有这个需求可不引入
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
//引入Vue3生命周期
import { onMounted } from 'vue'
2、创建场景
//创建一个三维场景
const scene = new THREE.Scene()
//添加光源 这里添加了两个光源
//AmbientLight:环境光源,均匀照亮所有物体,防止有些光源照射不到呈现不出来
//PointLight:点光源,类似灯泡发出的光,可以投射阴影,使模型更加立体
const ambientLight = new THREE.AmbientLight(0xffffff, 0.5),
pointLight = new THREE.PointLight(0xffffff, 0.4)
//设置点光源所在位置
pointLight.position.set(200,300,400)
//每创建一个object都需要将其添加到三维场景中
scene.add(ambientLight)
scene.add(pointLight)
//创建一个透视相机 这里的width、height是整个画布的宽高度
const width = window.innerWidth, height = window.innerHeight ,
camera = new THREE.PerspectiveCamera(45, width/height, 1, 1000)
//设置相机位置
camera.position.set(200,200,200)
//设置相机方向
camera.lookAt(0,0,0)
3、创建模型
//创建辅助坐标轴
const axesHelper = new THREE.AxesHelper(100)
scene.add(axesHelper)
//创建一个物体(形状)
const geometry = new THREE.BoxGeometry(100, 100, 100)
//创建材质(外观)
const material = new THREE.MeshLambertMaterial({
color: 0x00ffff,//设置材质颜色
transparent: true,//开启透明度
opacity: 0.5 //设置透明度
})
//创建一个网格模型对象,将上面设置好的物体及其材质注入到模型对象中
const mesh = new THREE.Mesh(geometry, material)
scene.add(mesh)
4、渲染
//创建一个WebGL渲染器
const renderer = new THREE.WebGLRenderer()
renderer.setSize(width,height)
renderer.render(scene,camera)
//vue3的生命周期钩子函数,渲染后执行(这是为了拿到dom节点)
onMounted(()=>{
//将渲染器绘制出的canvas添加到页面中
document.getElementById('three')?.appendChild(renderer.domElement)
})
5、扩展
以上四步已经可以生成一个带有辅助轴线的三维长方体模型
为了增加更多的可操作性,我们使用轨道控制器来对模型增加一些简单功能
//创建轨道控制器
const controls = new OrbitControls(camera, renderer.domElement)
//添加事件监听 当事件发生改变时触发
controls.addEventListener('change',()=>{
//重新渲染
renderer.render(scene, camera)
})
6、完整代码
<template>
<div id="three"></div>
</template>
<script lang='ts' setup>
import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
import { onMounted } from 'vue'
//创建一个三维场景
const scene = new THREE.Scene()
//添加光源
const ambient = new THREE.AmbientLight(0xffffff, 0.5),
light1 = new THREE.PointLight(0xffffff, 0.4),
light2 = new THREE.PointLight(0xffffff, 0.4)
scene.add(ambient)
light1.position.set(200,300,400)
scene.add(light1)
light2.position.set(-200,-300,-400)
scene.add(light2)
//创建一个透视相机
const width = window.innerWidth, height = window.innerHeight ,
camera = new THREE.PerspectiveCamera(45, width/height, 1, 1000)
//设置相机位置
camera.position.set(200,200,200)
//设置相机方向
camera.lookAt(0,0,0)
//创建辅助坐标轴
const axesHelper = new THREE.AxesHelper(100)
scene.add(axesHelper)
//创建一个物体(形状)
const geometry = new THREE.BoxGeometry(100, 100, 100)
//创建材质(外观)
const material = new THREE.MeshLambertMaterial({
color: 0x00ffff,//设置材质颜色
transparent: true,//开启透明度
opacity: 0.5 //设置透明度
})
//创建一个网格模型对象
const mesh = new THREE.Mesh(geometry, material)
//把网格模型添加到三维场景
scene.add(mesh)
//创建一个WebGL渲染器
const renderer = new THREE.WebGLRenderer()
renderer.setSize(width,height)
renderer.render(scene,camera)
const controls = new OrbitControls(camera, renderer.domElement)
controls.addEventListener('change',()=>{
renderer.render(scene, camera)
})
onMounted(()=>{
document.getElementById('three')?.appendChild(renderer.domElement)
})
</script>
<style lang='scss'>
body{
margin: 0;
padding: 0;
}
</style>