一、流水管线
实现逻辑:
1)先自定义几个点,通过CatmullRomCurve3生成一条平滑曲线
2)根据生成的曲线在XY面扩展一个面,其中需要注意顶点索引、UV坐标添加的顺序,否则可能会导致绘制的图片混乱,不是完整的图片
3)添加纹理同时设置偏移量实现流动效果
4)为了保证显示的箭头图标不失真,根据管线的长度和图标的长度动态计算repeat的个数
function addFlowByGeometry() { // 自定义点 const points = [ new THREE.Vector3(-5, 5, 0), new THREE.Vector3(-5, 0, 0), new THREE.Vector3(0, 0, 0), new THREE.Vector3(5, 0, 0), new THREE.Vector3(5, -5, 3), ]; // 生成一条平滑的曲线 const curve = new THREE.CatmullRomCurve3(points); const srcGeometry = new THREE.TubeGeometry(curve, 64, 0.8, 32, false); const srcMaterial = new THREE.MeshBasicMaterial({ color: 0x00ffff, transparent: true, opacity: 0.1, side: THREE.DoubleSide // 两面都显示 }); const srcMesh = new THREE.Mesh(srcGeometry, srcMaterial); scene.add(srcMesh); // 定义曲面的分辨率 const widthSegments = 32; const heightSegments = 32; // 定义顶点位置和纹理坐标 const vertices = []; const uvs = []; // 定义扩展宽度 const width = 0.5; for (let y = 0; y ) { for (let x = 0; x ) { const u = x / widthSegments; const v = y / heightSegments; // 获取曲线上的点 const point = curve.getPoint(u); // 获取曲线的切线向量 const tangent = curve.getTangent(u); // 计算法线向量 const normal = new THREE.Vector3(-tangent.y, tangent.x, 0).normalize(); // 扩展成平面 const px = point.x + normal.x * (v * 2 - 1) * width; const py = point.y + normal.y * (v * 2 - 1) * width; const pz = point.z; vertices.push(px, py, pz); uvs.push(u, v); } } // 定义顶点索引 const indices = []; for (let y = 0; y ) { for (let x = 0; x ) { const a = x + y * (widthSegments + 1); const b = x + 1 + y * (widthSegments + 1); const c = x + 1 + (y + 1) * (widthSegments + 1); const d = x + (y + 1) * (widthSegments + 1); indices.push(a, b, d); indices.push(b, c, d); } } // 创建一个自定义的 BufferGeometry const geometry = new THREE.BufferGeometry(); // 将顶点位置添加到几何体 geometry.setAttribute('position', new THREE.BufferAttribute(new Float32Array(vertices), 3)); // 将顶点索引添加到几何体 geometry.setIndex(new THREE.BufferAttribute(new Uint16Array(indices), 1)); // 将纹理坐标添加到几何体 geometry.setAttribute('uv', new THREE.BufferAttribute(new Float32Array(uvs), 2)); // 创建纹理加载器 const textureLoader = new THREE.TextureLoader(); // 加载纹理 const texture = textureLoader.load('Objects/imgs/arrow.png', () => { texture.wrapS = THREE.RepeatWrapping; texture.wrapT = THREE.RepeatWrapping; const originalWidth = texture.image.width; const originalHeight = texture.image.height; // 创建平面几何体 const [allWidth, allHeight] = [curve.getLength(), 1]; // 更新几何体的尺寸 texture.repeat.set(allWidth / (originalWidth * allHeight / 2 / originalHeight), 1); // 创建材质 const material = new THREE.MeshBasicMaterial({ map: texture, side: THREE.DoubleSide, color: 0x00ffff, wireframe: false }); // 创建网格 const mesh = new THREE.Mesh(geometry, material); // 将网格添加到场景中 scene.add(mesh); }); setInterval(() => { texture.offset.x -= 0.04; }, 30) }
流动管线
千百度
© 版权声明
1.本站内容仅供参考,不作为任何法律依据。用户在使用本站内容时,应自行判断其真实性、准确性和完整性,并承担相应风险。
2.本站部分内容来源于互联网,仅用于交流学习研究知识,若侵犯了您的合法权益,请及时邮件或站内私信与本站联系,我们将尽快予以处理。
3.本文采用知识共享 署名4.0国际许可协议 [BY-NC-SA] 进行授权
4.根据《计算机软件保护条例》第十七条规定“为了学习和研究软件内含的设计思想和原理,通过安装、显示、传输或者存储软件等方式使用软件的,可以不经软件著作权人许可,不向其支付报酬。”您需知晓本站所有内容资源均来源于网络,仅供用户交流学习与研究使用,版权归属原版权方所有,版权争议与本站无关,用户本人下载后不能用作商业或非法用途,需在24个小时之内从您的电脑中彻底删除上述内容,否则后果均由用户承担责任;如果您访问和下载此文件,表示您同意只将此文件用于参考、学习而非其他用途,否则一切后果请您自行承担,如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。
5.本站是非经营性个人站点,所有软件信息均来自网络,所有资源仅供学习参考研究目的,并不贩卖软件,不存在任何商业目的及用途
THE END
暂无评论内容