一、Three.js技术选型与基础环境搭建
Three.js作为主流的WebGL JavaScript库,通过封装底层图形API简化了3D开发流程。项目初始化建议采用模块化方案,可通过npm/pnpm安装最新稳定版本:
pnpm add three
在Vue/React等现代框架中,建议将3D容器与业务逻辑分离。以下是一个典型的Vue单文件组件结构:
<template><div class="three-container"><canvas ref="canvasRef"></canvas></div></template><script setup>import { onMounted, ref } from 'vue'import * as THREE from 'three'const canvasRef = ref(null)// 后续初始化代码将挂载在此</script><style scoped>.three-container {position: fixed;top: 0;left: 0;width: 100vw;height: 100vh;overflow: hidden;}canvas {display: block;}</style>
这种结构确保了3D渲染区域全屏覆盖,同时避免页面布局冲突。
二、核心场景对象初始化
1. 场景系统构建
场景(Scene)是3D对象的容器,支持动态添加/移除元素。初始化时应考虑:
const scene = new THREE.Scene()// 背景设置支持纯色和纹理两种方式scene.background = new THREE.Color(0xf0f0f0) // 纯色背景// 或使用纹理加载器const textureLoader = new THREE.TextureLoader()textureLoader.load('path/to/texture.jpg', (texture) => {texture.mapping = THREE.EquirectangularReflectionMappingscene.background = texturescene.environment = texture // 同时设置环境贴图})
2. 坐标系可视化
辅助工具对于调试至关重要,AxesHelper能直观显示三维坐标系:
const axesHelper = new THREE.AxesHelper(1000) // 参数为坐标轴长度scene.add(axesHelper)
建议开发阶段保持显示,生产环境可通过条件判断移除。
三、光照系统设计
合理的光照配置能显著提升3D场景的真实感,推荐组合使用:
1. 平行光(DirectionalLight)
模拟太阳光等远距离光源:
const directionalLight = new THREE.DirectionalLight(0xffffff, 1)directionalLight.position.set(100, 60, 50)// 可添加阴影配置directionalLight.castShadow = truedirectionalLight.shadow.mapSize.width = 2048directionalLight.shadow.mapSize.height = 2048scene.add(directionalLight)
2. 环境光(AmbientLight)
补充场景基础亮度,避免纯阴影区域:
const ambientLight = new THREE.AmbientLight(0xffffff, 0.4)scene.add(ambientLight)
3. 进阶方案
对于复杂场景,可组合使用点光源(PointLight)、聚光灯(SpotLight)和半球光(HemisphereLight),但需注意性能开销。
四、相机系统配置
相机决定了观察者的视角,常用透视相机配置示例:
const camera = new THREE.PerspectiveCamera(45, // 视野角度window.innerWidth / window.innerHeight, // 宽高比1, // 近裁剪面500 // 远裁剪面)camera.position.set(200, 180, 0)camera.lookAt(0, 0, 0) // 指向场景中心
响应式设计需监听窗口变化:
window.addEventListener('resize', () => {camera.aspect = window.innerWidth / window.innerHeightcamera.updateProjectionMatrix()renderer.setSize(window.innerWidth, window.innerHeight)})
五、WebGL渲染器优化
渲染器是最终图像输出的核心组件,关键配置项包括:
const renderer = new THREE.WebGLRenderer({antialias: true, // 抗锯齿alpha: true, // 允许透明背景powerPreference: "high-performance" // 性能优先})renderer.setPixelRatio(window.devicePixelRatio) // 高DPI适配renderer.shadowMap.enabled = true // 启用阴影renderer.setSize(window.innerWidth, window.innerHeight)document.body.appendChild(renderer.domElement)
对于移动端,建议添加性能检测:
if (!WebGL.isWebGLAvailable()) {const warning = WebGL.getWebGLErrorMessage()document.body.appendChild(warning)}
六、动画循环与交互控制
1. 基础动画循环
使用requestAnimationFrame实现流畅动画:
function animate() {requestAnimationFrame(animate)// 更新场景对象状态renderer.render(scene, camera)}animate()
2. 轨道控制器集成
引入OrbitControls实现鼠标交互:
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'const controls = new OrbitControls(camera, renderer.domElement)controls.enableDamping = true // 启用阻尼效果controls.dampingFactor = 0.05
需在动画循环中更新控制器:
function animate() {requestAnimationFrame(animate)controls.update() // 必须调用renderer.render(scene, camera)}
七、性能优化实践
- 对象池技术:复用几何体和材质,避免频繁创建销毁
- 层级管理:使用THREE.Group组织相关对象
- LOD策略:根据距离切换不同精度模型
- WebGL状态管理:减少不必要的状态变更
- 工作线程:复杂计算可移至Web Worker
八、完整初始化流程示例
// 初始化函数function initThreeScene() {// 1. 创建场景const scene = new THREE.Scene()scene.background = new THREE.Color(0x87CEEB)// 2. 添加辅助工具const axesHelper = new THREE.AxesHelper(100)scene.add(axesHelper)// 3. 配置光源const directionalLight = new THREE.DirectionalLight(0xffffff, 1)directionalLight.position.set(100, 100, 50)scene.add(directionalLight)scene.add(new THREE.AmbientLight(0x404040))// 4. 设置相机const camera = new THREE.PerspectiveCamera(45,window.innerWidth / window.innerHeight,0.1,1000)camera.position.set(5, 5, 5)camera.lookAt(0, 0, 0)// 5. 初始化渲染器const renderer = new THREE.WebGLRenderer({ antialias: true })renderer.setSize(window.innerWidth, window.innerHeight)renderer.setAnimationLoop(animate)document.body.appendChild(renderer.domElement)// 6. 添加控制器const controls = new OrbitControls(camera, renderer.domElement)controls.target.set(0, 0, 0)function animate() {controls.update()renderer.render(scene, camera)}return { scene, camera, renderer }}
通过以上系统化的实践指南,开发者能够构建出性能优良、交互流畅的WebGL 3D场景。后续可进一步探索模型加载、着色器编程、物理引擎集成等高级主题。