当前位置: 首页 > news >正文

16.three官方示例+编辑器+AI快速学习webgl_buffergeometry_lines_indexed

本实例主要讲解内容

这个Three.js示例展示了如何使用**索引几何体(Indexed Geometry)**创建复杂的分形线条图案。通过递归算法生成科赫雪花(Koch Snowflake)曲线,并利用索引缓冲区优化顶点数据存储,实现高效的线条渲染。

核心技术包括:

  • 索引几何体的创建与应用
  • 递归算法生成复杂分形图案
  • 顶点颜色的使用
  • 高效线条渲染技术

在这里插入图片描述

完整代码注释

<!DOCTYPE html>
<html lang="en"><head><title>three.js webgl - buffergeometry - lines - indexed</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 - indexed</div><script type="importmap">{"imports": {"three": "../build/three.module.js","three/addons/": "./jsm/"}}</script><script type="module">import * as THREE from 'three';import Stats from 'three/addons/libs/stats.module.js';let container, stats;let camera, scene, renderer;let parent_node;init();function init() {container = document.getElementById( 'container' );// 初始化相机camera = new THREE.PerspectiveCamera( 27, window.innerWidth / window.innerHeight, 1, 10000 );camera.position.z = 9000;// 初始化场景scene = new THREE.Scene();// 创建几何体和材质const geometry = new THREE.BufferGeometry();// 使用顶点颜色的线材质const material = new THREE.LineBasicMaterial( { vertexColors: true } );// 存储索引、位置和颜色数据const indices = [];const positions = [];const colors = [];let next_positions_index = 0;// 分形迭代次数const iteration_count = 4;// 旋转角度(用于科赫曲线)const rangle = 60 * Math.PI / 180.0;// 添加顶点到几何体function add_vertex( v ) {positions.push( v.x, v.y, v.z );// 为每个顶点设置随机颜色(偏蓝色调)colors.push( Math.random() * 0.5 + 0.5, Math.random() * 0.5 + 0.5, 1 );return next_positions_index ++;}// 科赫曲线递归生成函数function snowflake_iteration( p0, p4, depth ) {// 递归终止条件if ( -- depth < 0 ) {// p0已经添加,获取其索引const i = next_positions_index - 1;// 添加p4顶点add_vertex( p4 );// 添加一条从p0到p4的线indices.push( i, i + 1 );return;}// 计算线段的1/3和2/3点const v = p4.clone().sub( p0 );const v_tier = v.clone().multiplyScalar( 1 / 3 );const p1 = p0.clone().add( v_tier );// 计算向外凸起的点p2const angle = Math.atan2( v.y, v.x ) + rangle;const length = v_tier.length();const p2 = p1.clone();p2.x += Math.cos( angle ) * length;p2.y += Math.sin( angle ) * length;// 计算线段的2/3点const p3 = p0.clone().add( v_tier ).add( v_tier );// 递归处理四个子线段snowflake_iteration( p0, p1, depth );snowflake_iteration( p1, p2, depth );snowflake_iteration( p2, p3, depth );snowflake_iteration( p3, p4, depth );}// 生成雪花图案function snowflake( points, loop, x_offset ) {for ( let iteration = 0; iteration != iteration_count; iteration ++ ) {// 添加起始顶点add_vertex( points[ 0 ] );// 处理所有线段for ( let p_index = 0, p_count = points.length - 1; p_index != p_count; p_index ++ ) {snowflake_iteration( points[ p_index ], points[ p_index + 1 ], iteration );}// 如果是闭合图形,连接最后一个点和第一个点if ( loop ) snowflake_iteration( points[ points.length - 1 ], points[ 0 ], iteration );// 为下一次迭代平移输入曲线for ( let p_index = 0, p_count = points.length; p_index != p_count; p_index ++ ) {points[ p_index ].x += x_offset;}}}// 生成不同形状的科赫曲线let y = 0;// 线段科赫曲线snowflake([new THREE.Vector3( 0, y, 0 ),new THREE.Vector3( 500, y, 0 )],false, 600);y += 600;// 三角形科赫雪花snowflake([new THREE.Vector3( 0, y, 0 ),new THREE.Vector3( 250, y + 400, 0 ),new THREE.Vector3( 500, y, 0 )],true, 600);y += 600;// 矩形科赫雪花snowflake([new THREE.Vector3( 0, y, 0 ),new THREE.Vector3( 500, y, 0 ),new THREE.Vector3( 500, y + 500, 0 ),new THREE.Vector3( 0, y + 500, 0 )],true, 600);y += 1000;// 星形科赫曲线snowflake([new THREE.Vector3( 250, y, 0 ),new THREE.Vector3( 500, y, 0 ),new THREE.Vector3( 250, y, 0 ),new THREE.Vector3( 250, y + 250, 0 ),new THREE.Vector3( 250, y, 0 ),new THREE.Vector3( 0, y, 0 ),new THREE.Vector3( 250, y, 0 ),new THREE.Vector3( 250, y - 250, 0 ),new THREE.Vector3( 250, y, 0 )],false, 600);// 设置几何体的索引和属性geometry.setIndex( indices );geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( positions, 3 ) );geometry.setAttribute( 'color', new THREE.Float32BufferAttribute( colors, 3 ) );geometry.computeBoundingSphere();// 创建线段对象const lineSegments = new THREE.LineSegments( geometry, material );lineSegments.position.x -= 1200;lineSegments.position.y -= 1200;// 创建父对象parent_node = new THREE.Object3D();parent_node.add( lineSegments );// 添加到场景scene.add( parent_node );// 初始化渲染器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() {const time = Date.now() * 0.001;// 旋转整个场景parent_node.rotation.z = time * 0.5;// 渲染场景renderer.render( scene, camera );// 更新性能统计stats.update();}</script></body>
</html>

索引几何体技术解析

什么是索引几何体

索引几何体(Indexed Geometry)是一种优化的顶点数据存储方式,它将共享的顶点只存储一次,通过索引数组来引用这些顶点。与非索引几何体相比,索引几何体有以下优势:

  1. 减少内存占用:对于有大量共享顶点的模型,可显著减少顶点数据量
  2. 提高渲染效率:减少GPU需要处理的顶点数量
  3. 简化模型数据:使模型数据结构更加清晰

在Three.js中,我们通过geometry.setIndex()方法来设置索引数据。

科赫雪花算法

科赫雪花是一种经典的分形曲线,其构造方法如下:

  1. 基本线段:从一条线段开始
  2. 分割线段:将线段分成三等份
  3. 替换中间段:将中间的三分之一线段替换为一个等边三角形的两条边
  4. 递归处理:对新生成的每条线段重复上述过程

本示例中的递归函数snowflake_iteration实现了这一过程:

function snowflake_iteration( p0, p4, depth ) {// 递归终止条件if ( -- depth < 0 ) {// 添加线段return;}// 计算线段的1/3和2/3点// 计算向外凸起的点p2// 递归处理四个子线段
}
顶点颜色的使用

本示例使用了顶点颜色来为线条添加变化:

  1. 材质设置:使用LineBasicMaterial并启用vertexColors: true
  2. 顶点颜色数据:为每个顶点设置RGB颜色值
  3. 插值效果:GPU会自动在两个顶点之间进行颜色插值
// 设置材质
const material = new THREE.LineBasicMaterial( { vertexColors: true } );// 添加顶点时设置颜色
function add_vertex( v ) {positions.push( v.x, v.y, v.z );colors.push( Math.random() * 0.5 + 0.5, Math.random() * 0.5 + 0.5, 1 );return next_positions_index ++;
}
性能优化与应用场景

索引几何体特别适合以下场景:

  1. 复杂网格模型:如角色模型、建筑模型等
  2. 共享顶点的几何体:如平面、立方体等
  3. 大量重复图案:如本示例中的分形图案

性能优化建议:

  1. 合并几何体:对于静态场景,考虑将多个几何体合并为一个以减少绘制调用
  2. 使用BufferGeometry:相比普通Geometry,BufferGeometry性能更高
  3. 优化索引数据:合理安排顶点顺序,提高缓存命中率
  4. 控制递归深度:如本示例中的迭代次数,过深的递归会导致顶点数量爆炸式增长

索引几何体是Three.js中一项重要的优化技术,在处理复杂模型和大量线条时能带来显著的性能提升。

相关文章:

  • 嵌入式软件--stm32 DAY 6 USART串口通讯(下)
  • js fetch流式请求 AI动态生成文本,实现逐字生成渲染效果
  • 「光域」系列激光测距传感器:以光为尺,重构空间认知边界
  • Python 处理图像并生成 JSONL 元数据文件 - 固定text版本
  • Oracle19c中的全局临时表
  • 使用vite重构vue-cli的vue3项目
  • TDengine 在金融领域的应用
  • 《Head First 设计模式》第一章 - 笔记
  • 【ASR学习笔记】:语音识别领域基本术语
  • web 自动化之 Unittest 四大组件
  • 一个.Net开发的、用于自动化测试Windows应用程序的开源框架
  • Wpf学习片段
  • 从海洋生物找灵感:造个机器人RoboPteropod,它能在水下干啥?
  • 当生产了~/qt-arm/bin/qmake,可以单独编译其他-源码的某个模块,如下,编译/qtmultimedia
  • Hadoop区别
  • ElasticSearch聚合操作案例
  • 基于MCP的智能体架构设计:实现智能体与外部世界的无缝连接
  • 【NextPilot日志移植】ULog
  • 【免费】2005-2018年各省人均财政收支数据
  • HTTPS全解析:从证书签发到TLS握手优化
  • 网站logo怎么修改/济南网站制作
  • 一家公司可以做几个网站/百度热搜电视剧
  • 闸北做网站/优化软件seo排名
  • 上海做网站推荐/厦门seo关键词排名
  • wordpress支付集成/灰色词seo排名
  • 谷歌网站建设/博客推广工具