17.three官方示例+编辑器+AI快速学习webgl_buffergeometry_lines
本实例主要讲解内容
这个Three.js示例展示了如何使用BufferGeometry创建大量线段,并通过**变形目标(Morph Targets)**实现动态变形效果。通过随机生成的点云数据,结合顶点颜色和变形动画,创建出一个视觉效果丰富的3D线条场景。
核心技术包括:
- BufferGeometry的高效使用
- 顶点颜色的应用
- 变形目标动画技术
- 动态场景性能优化
完整代码注释
<!DOCTYPE html>
<html lang="en"><head><title>three.js webgl - buffergeometry - lines</title><meta charset="utf-8"><meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0"><link type="text/css" rel="stylesheet" href="main.css"></head><body><div id="container"></div><div id="info"><a href="https://threejs.org" target="_blank" rel="noopener">three.js</a> webgl - buffergeometry - lines</div><script type="importmap">{"imports": {"three": "../build/three.module.js","three/addons/": "./jsm/"}}</script><script type="module">import * as THREE from 'three';import { Timer } from 'three/addons/misc/Timer.js';import Stats from 'three/addons/libs/stats.module.js';let container, stats, timer;let camera, scene, renderer;let line;// 线段数量const segments = 10000;// 范围半径const r = 800;// 动画时间变量let t = 0;init();function init() {container = document.getElementById( 'container' );// 初始化相机camera = new THREE.PerspectiveCamera( 27, window.innerWidth / window.innerHeight, 1, 4000 );camera.position.z = 2750;// 初始化场景scene = new THREE.Scene();// 初始化计时器timer = new Timer();timer.connect( document );// 创建几何体和材质const geometry = new THREE.BufferGeometry();// 使用顶点颜色的线材质const material = new THREE.LineBasicMaterial( { vertexColors: true } );// 存储位置和颜色数据const positions = [];const colors = [];// 生成随机点云数据for ( let i = 0; i < segments; i ++ ) {// 随机位置const x = Math.random() * r - r / 2;const y = Math.random() * r - r / 2;const z = Math.random() * r - r / 2;// 添加位置数据positions.push( x, y, z );// 添加颜色数据(基于位置归一化)colors.push( ( x / r ) + 0.5 );colors.push( ( y / r ) + 0.5 );colors.push( ( z / r ) + 0.5 );}// 设置几何体属性geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( positions, 3 ) );geometry.setAttribute( 'color', new THREE.Float32BufferAttribute( colors, 3 ) );// 生成变形目标generateMorphTargets( geometry );// 计算边界球体,用于视锥体剔除geometry.computeBoundingSphere();// 创建线条对象line = new THREE.Line( geometry, material );scene.add( line );// 初始化渲染器renderer = new THREE.WebGLRenderer();renderer.setPixelRatio( window.devicePixelRatio );renderer.setSize( window.innerWidth, window.innerHeight );renderer.setAnimationLoop( animate );container.appendChild( renderer.domElement );// 添加性能统计stats = new Stats();container.appendChild( stats.dom );// 窗口大小变化事件监听window.addEventListener( 'resize', onWindowResize );}// 窗口大小变化处理函数function onWindowResize() {camera.aspect = window.innerWidth / window.innerHeight;camera.updateProjectionMatrix();renderer.setSize( window.innerWidth, window.innerHeight );}// 动画循环function animate() {// 更新计时器timer.update();// 获取时间增量和总时间const delta = timer.getDelta();const time = timer.getElapsed();// 旋转整个线条对象line.rotation.x = time * 0.25;line.rotation.y = time * 0.5;// 更新变形目标影响因子t += delta * 0.5;line.morphTargetInfluences[ 0 ] = Math.abs( Math.sin( t ) );// 渲染场景renderer.render( scene, camera );// 更新性能统计stats.update();}// 生成变形目标function generateMorphTargets( geometry ) {// 存储变形目标的位置数据const data = [];// 生成随机目标位置for ( let i = 0; i < segments; i ++ ) {const x = Math.random() * r - r / 2;const y = Math.random() * r - r / 2;const z = Math.random() * r - r / 2;data.push( x, y, z );}// 创建变形目标属性const morphTarget = new THREE.Float32BufferAttribute( data, 3 );morphTarget.name = 'target1';// 设置几何体的变形目标geometry.morphAttributes.position = [ morphTarget ];}</script></body>
</html>
BufferGeometry与变形目标技术解析
BufferGeometry的优势
BufferGeometry是Three.js中最高效的几何体表示方式,相比普通Geometry,它有以下优势:
- 内存效率高:以连续数组形式存储顶点数据,更接近GPU原生格式
- 渲染速度快:减少CPU-GPU数据传输开销
- 支持大规模场景:能够处理数百万个顶点
- 灵活的数据组织:可以自定义顶点属性
在本示例中,我们使用BufferGeometry存储顶点位置和颜色数据:
const geometry = new THREE.BufferGeometry();// 创建位置和颜色数据数组
const positions = [];
const colors = [];// 填充数据...// 设置几何体属性
geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( positions, 3 ) );
geometry.setAttribute( 'color', new THREE.Float32BufferAttribute( colors, 3 ) );
变形目标动画
变形目标(Morph Targets)是一种基于顶点的动画技术,通过在不同顶点位置之间插值实现平滑变形效果。主要步骤包括:
- 定义基础几何体:原始顶点位置
- 定义变形目标:一个或多个目标顶点位置
- 控制影响因子:通过影响因子控制变形程度(0.0-1.0)
在本示例中,我们实现了一个变形目标:
// 生成变形目标数据
function generateMorphTargets( geometry ) {const data = [];// 生成随机目标位置...// 创建变形目标属性const morphTarget = new THREE.Float32BufferAttribute( data, 3 );morphTarget.name = 'target1';// 设置几何体的变形目标geometry.morphAttributes.position = [ morphTarget ];
}// 在动画循环中控制变形程度
line.morphTargetInfluences[ 0 ] = Math.abs( Math.sin( t ) );
顶点颜色应用
顶点颜色允许为每个顶点指定不同的颜色,GPU会自动在顶点之间进行插值,产生平滑的渐变效果。使用顶点颜色的步骤:
- 材质设置:在材质中启用vertexColors
- 提供颜色数据:为每个顶点提供RGB颜色值
在本示例中:
// 创建启用顶点颜色的材质
const material = new THREE.LineBasicMaterial( { vertexColors: true } );// 为每个顶点生成颜色数据(基于位置)
colors.push( ( x / r ) + 0.5 );
colors.push( ( y / r ) + 0.5 );
colors.push( ( z / r ) + 0.5 );// 设置几何体的颜色属性
geometry.setAttribute( 'color', new THREE.Float32BufferAttribute( colors, 3 ) );
性能优化与应用场景
对于大规模线条渲染的性能优化建议:
- 使用BufferGeometry:相比普通Geometry,性能提升显著
- 合并几何体:如果可能,将多个线条合并为一个
- 合理使用变形目标:每个变形目标都会增加内存使用
- 控制顶点数量:过多顶点会导致性能下降
- 视锥体剔除:确保几何体有正确的边界球体
这种技术适合以下场景:
- 数据可视化(点云、网络图等)
- 粒子系统
- 动态线条艺术
- 模拟流体、烟雾等效果
通过结合BufferGeometry、顶点颜色和变形目标,我们可以创建出视觉效果丰富且性能高效的动态线条场景。
交流学习: Three.js 场景编辑器 (Vue3 + TypeScript
实现)
https://threelab.cn/threejs-edit/