Three.js 飞线效果
需求:
实现一个线条流动的效果,
实现方案:
1. 贴图+管道+贴图偏移 方案(这里暂不做介绍)
2. 向量+弧线+模型 方案
实现:
1.获取到需要实现效果的路径顶点信息
var geometrys = new THREE.Geometry() var materialA = new THREE.MeshStandardMaterial({ color: 0x00ffff,side: THREE.DoubleSide }); const geometry = new THREE.BoxGeometry(); for ( let i = 0; i < number; i ++ ) { const mesh = new THREE.Mesh( geometry, materialA ); mesh.position.x = Math.random() * 1600 - 800; mesh.position.y = 20; mesh.position.z = Math.random() * 1600 - 800; // mesh.scale.x = 20; mesh.scale.y = Math.random() * 80 + 10; // mesh.scale.z = 20; mesh.updateMatrix(); mesh.matrixAutoUpdate = false; mesh.name = 'boxA'; // mesh.shader = shader; // const axesHelper = new THREE.AxesHelper(100); // mesh.add(axesHelper); // console.log('顶点位置', mesh); geometrys.merge(mesh.geometry, mesh.matrix); this.pointslists.push(mesh.position) } const newMesh = new THREE.Mesh( geometrys, material ); newMesh.name = 'boxB'; // const a = new THREE.Euler(10, 0, 10, 'ZYX'); // 欧拉角 // newMesh.rotation.setFromVector3(a); this.scene.add( newMesh );
2.创建路径线条+箭头模型
FlylineModel(){ let that=this // 飞线模型 this.flyGroup = new THREE.Group(); var geometry = new THREE.BufferGeometry(); //创建一个缓冲类型几何体 // 三维样条曲线 console.log(this.pointslists.length); // this.pointslists.sort((a, b) => a.z - b.z) var curve = new THREE.CatmullRomCurve3(this.pointslists); curve.closed = true; console.log(`整个线段的已知点位中心位置:`,curve.getPoint(0.5), `弧长上的实际中心点位:`,curve.getPointAt(0.5) ); //曲线上等间距返回多个顶点坐标 that.points = curve.getPoints(100); //分段数100,返回101个顶点 // that.points = curve.getPoints(curve.getLength()/100); //按整体长度的10/1的长度进行分段 // 上面这俩的区别是一个是按已知点进行分段,一个是按曲线的实际长度进行分段 // console.log(this.points) // setFromPoints方法从points中提取数据赋值给attributes.position geometry.setFromPoints(that.points); var material = new THREE.LineBasicMaterial({ color: 0x5588aa, //轨迹颜色 }); //线条模型对象 var line = new THREE.Line(geometry, material); line.scale.set(2, 0, 2); this.flyGroup.add(line); index = 1; //取点索引位置 num = 15; //从曲线上获取点数量 points2 = that.points.slice(index, index + num); //从曲线上获取一段 // var curve = new THREE.CatmullRomCurve3(points2); // var newPoints2 = curve.getPoints(100); //获取更多的点数 geometry2 = new THREE.BufferGeometry(); geometry2.setFromPoints(that.points); // 每个顶点对应一个百分比数据attributes.percent 用于控制点的渲染大小 var percentArr = []; //attributes.percent的数据 for (var i = 0; i < that.points.length; i++) { percentArr.push(i / that.points.length); } var percentAttribue = new THREE.BufferAttribute(new Float32Array(percentArr), 1); geometry2.attributes.percent = percentAttribue; // 批量计算所有顶点颜色数据 var colorArr = []; for (var i = 0; i < that.points.length; i++) { var color1 = new THREE.Color(0x5588aa); //轨迹线颜色 青色 var color2 = new THREE.Color(0xef4136); // var color = color1.lerp(color2, i / that.points.length) colorArr.push(color.r, color.g, color.b); } // 设置几何体顶点颜色数据 geometry2.attributes.color = new THREE.BufferAttribute(new Float32Array(colorArr), 3); // 点模型渲染几何体每个顶点 var PointsMaterial = new THREE.PointsMaterial({ // color: 0xffff00, size: 50.0, //点大小 vertexColors: THREE.VertexColors, //使用顶点颜色渲染 }); var flyPoints = new THREE.Points(geometry2, PointsMaterial); flyPoints.scale.set(2, 0, 2); // 修改点材质的着色器源码(注意:不同版本细节可能会稍微会有区别,不过整体思路是一样的) PointsMaterial.onBeforeCompile = function (shader) { // 顶点着色器中声明一个attribute变量:百分比 shader.vertexShader = shader.vertexShader.replace( 'void main() {', [ 'attribute float percent;', //顶点大小百分比变量,控制点渲染大小 'void main() {', ].join('\n') // .join()把数组元素合成字符串 ); // 调整点渲染大小计算方式 shader.vertexShader = shader.vertexShader.replace( 'gl_PointSize = size;', [ 'gl_PointSize = percent * size;', ].join('\n') // .join()把数组元素合成字符串 ); }; this.flyGroup.add(flyPoints); this.scene.add(this.flyGroup); // 飞线动画 indexMax = this.points.length - num; //飞线取点索引范围 },
3.更新箭头位置
update() { let that = this // 飞线动画 if(that.points){ if (index > indexMax) index = 0; index += 1 points2 = that.points.slice(index, index + num); // 从曲线上获取一段 // console.log(points2) var curve = new THREE.CatmullRomCurve3(points2); var newPoints2 = curve.getPoints(100); // 获取更多的点数 geometry2.setFromPoints(newPoints2); // this.camera.position.copy(curve.getPoint(2)) } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?