如何使用@react-three/fiber基于bufferGeometry绘制自定义顶点网格
非索引版实现(直接使用你提供的顶点数组)
直接将顶点数组转换为Three.js要求的类型化数组,传入bufferAttribute即可:
import { useMemo } from 'react'; import * as THREE from 'three'; function CustomMesh() { const vertices = useMemo(() => new Float32Array([ 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 1.0, // 剩余顶点数据 ]), []); return ( <mesh> <bufferGeometry> <bufferAttribute attach="attributes.position" array={vertices} count={vertices.length / 3} itemSize={3} /> </bufferGeometry> <meshLambertMaterial attach="material" color="hotpink" side={THREE.DoubleSide} /> </mesh> ); }
索引优化版实现
对于存在大量重复顶点的场景,使用索引可以大幅降低内存占用,性能更好:
import { useMemo } from 'react'; import * as THREE from 'three'; function IndexedCustomMesh() { // 去重后的顶点集合 const vertices = useMemo(() => new Float32Array([ 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 1.0 ]), []); // 索引数组,指定每个三角形的顶点索引 const indices = useMemo(() => new Uint16Array([ 0, 1, 2, // 第一个三角形 1, 3, 2 // 第二个三角形 ]), []); return ( <mesh> <bufferGeometry index={indices}> <bufferAttribute attach="attributes.position" array={vertices} count={vertices.length / 3} itemSize={3} /> </bufferGeometry> <meshLambertMaterial attach="material" color="hotpink" side={THREE.DoubleSide} /> </mesh> ); }
注意事项
- 顶点、索引数据必须使用类型化数组(Float32Array、Uint16Array等),不能直接传入普通JS数组
- 所有固定的几何数据建议用
useMemo包裹,避免组件重渲染时反复生成数据、触发几何体重计算 - 若出现图形不可见的情况,优先检查两点:一是顶点坐标是否在相机视锥体范围内,二是给材质添加
side={THREE.DoubleSide}关闭单面剔除 - 如需添加法向量、UV坐标等属性,新增对应
bufferAttribute标签即可,attach属性分别设置为attributes.normal、attributes.uv,其余参数规则和position属性一致
内容的提问来源于stack exchange,提问作者Trip1eLift
相关产品推荐
相关产品推荐

