目标

  • 了解一下three.js
  • 在vue3项目中,创建一个立方体(原理都一样)

Three.js简介与基础概念

  • Three.js是一个基于WebGL的JavaScript库,用于在浏览器中创建3D图形
  • 核心概念包括场景(Scene)、相机(Camera)和渲染器(Renderer)
  • 几何体(Geometry)和材质(Material)是构建3D对象的基本元素

我们之后的代码在以前创建好的vue3+ts项目中去辨析额,可以参考:从零到一搭建:vue3+vite7+antfu+stylelint+githooks,全流程配置,附带源码,集成css变量使用,下载即用,去自己创建一个项目。

环境准备与项目设置

安装依赖

pnpm i -D three @types/three

创建基础Three.js场景

初始化场景对象

import * as THREE from 'three'
// 1.创建场景
const scene = new THREE.Scene()

设置透视相机(PerspectiveCamera)参数,并设置相机位置

// 2.创建相机
const camera = new THREE.PerspectiveCamera(
  75,
  window.innerWidth / window.innerHeight,
  0.1,
  1000,
)
camera.position.set(0, 0, 10)
scene.add(camera)

配置WebGL渲染器并添加到DOM,这一步在vue中需要在挂载完毕之后,因此需要将下面代码写入onMounted钩子函数之中
并且需要准备一个canvas

<template>
  <canvas id="canvasThree" ref="canvasThree" />
</template>
import { onMounted, ref } from 'vue'

const canvasThree = ref()

// 创建渲染器
const renderer = new THREE.WebGLRenderer({ antialias: true, canvas: canvasThree.value })

// 设置渲染器尺寸
renderer.setSize(window.innerWidth, window.innerHeight)

// 渲染场景
renderer.render(scene, camera)

创建立方体几何体

使用BoxGeometry定义立方体形状,设置立方体尺寸参数(宽度、高度、深度),理解几何体的顶点和面结构

// 3.创建物体(几何体 + 材质 = 物体)
const boxWidth = 1
const boxHeight = 1
const boxDepth = 1
const geometry = new THREE.BoxGeometry(boxWidth, boxHeight, boxDepth)

const material = new THREE.MeshBasicMaterial({ color: 0x44AA88 })

const cube = new THREE.Mesh(geometry, material)

scene.add(cube)

设置材质

基本材质类型介绍:MeshBasicMaterial、MeshNormalMaterial等,设置材质颜色和属性,上面代码已经包含

在这里插入图片描述

完整代码示例

完整代码如下,但需要再项目中运行,可以下载资源

<script setup lang="ts">
import * as THREE from 'three'
import { onMounted, ref } from 'vue'

const canvasThree = ref()

// 1.创建场景
const scene = new THREE.Scene()

// 2.创建相机
const camera = new THREE.PerspectiveCamera(
  75,
  window.innerWidth / window.innerHeight,
  0.1,
  1000,
)
camera.position.set(0, 0, 10)
scene.add(camera)

// 3.创建物体(几何体 + 材质 = 物体)
const boxWidth = 1
const boxHeight = 1
const boxDepth = 1
const geometry = new THREE.BoxGeometry(boxWidth, boxHeight, boxDepth)

const material = new THREE.MeshBasicMaterial({ color: 0x44AA88 })

const cube = new THREE.Mesh(geometry, material)

scene.add(cube)

onMounted(() => {
  // 创建渲染器
  const renderer = new THREE.WebGLRenderer({ antialias: true, canvas: canvasThree.value })

  // 设置渲染器尺寸
  renderer.setSize(window.innerWidth, window.innerHeight)

  // 渲染场景
  renderer.render(scene, camera)
})
</script>

<template>
  <canvas id="canvasThree" ref="canvasThree" />
</template>

特别说明

以上就是完整的代码与逻辑,其实非常简单。但是有一个思路,就是了解其结构,从对象的角度。
比如:对象中有数据与方法。
数据——就是对象的结构。
方法——就是对象上都能有哪些功能。

因此,主要了解一下渲染一个立方体,我们可以在屏幕上看到它,是需要哪些组成的结构(场景、相机、渲染、以及立方体)。因此,我们把代码改为如下代码,体会一下

<script setup lang="ts">
import * as THREE from 'three'
import { onMounted, ref } from 'vue'

const canvasThree = ref()

// 创建scene、camera、renderer
let scene: THREE.Scene, camera: THREE.PerspectiveCamera, renderer: THREE.WebGLRenderer, cube: THREE.Mesh

// 1.创建场景
function initScene() {
  scene = new THREE.Scene()
}

// 2.创建相机
function initCamera() {
  camera = new THREE.PerspectiveCamera(
    75,
    window.innerWidth / window.innerHeight,
    0.1,
    1000,
  )
  camera.position.set(0, 0, 10)
  scene.add(camera)
}

// 3.创建物体(几何体 + 材质 = 物体)
function initCube() {
  const boxWidth = 1
  const boxHeight = 1
  const boxDepth = 1
  const geometry = new THREE.BoxGeometry(boxWidth, boxHeight, boxDepth)

  const material = new THREE.MeshBasicMaterial({ color: 0x44AA88 })

  cube = new THREE.Mesh(geometry, material)

  scene.add(cube)
}

// 4.渲染场景
function initRenderer() {
  // 创建渲染器
  renderer = new THREE.WebGLRenderer({ antialias: true, canvas: canvasThree.value })

  // 设置渲染器尺寸
  renderer.setSize(window.innerWidth, window.innerHeight)

  // 渲染场景
  renderer.render(scene, camera)
}

onMounted(() => {
  // 初始化场景、相机、物体
  initScene()
  initCamera()
  initCube()

  // 初始化渲染器
  initRenderer()
})
</script>

<template>
  <canvas id="canvasThree" ref="canvasThree" />
</template>

这样写,也算是养成一个习惯,封装的习惯也好,结构分明的习惯也好,为了后续做准备也好,我总觉得这样是一个好的开始,有问题可以探讨下…

另外大家可以参考webgl,中是如何画一个点。WebGL学习及项目实战(第02期:绘制一个点)

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐