首页 / three.js / API 文档
BufferAttribute
先看结论
顶点属性缓冲区。几何体的位置、法线、颜色、UV 都以它的形式存在, 本质是一段 TypedArray 加上「每个顶点占几个分量」的描述。
new THREE.BufferAttribute(array, itemSize, normalized)
构造参数
| 参数 | 默认 | 说明 |
|---|---|---|
array | 必填 | TypedArray,长度必须是 itemSize 的整数倍 |
itemSize | 必填 | 每个顶点占用的分量数,位置与法线为 3,UV 为 2,颜色为 3 或 4 |
normalized | false | true 时把整数型缓冲映射到 0 到 1(或 -1 到 1) |
属性
| 属性 | 说明 |
|---|---|
array | 底层 TypedArray |
itemSize | 每顶点分量数 |
count | 只读,顶点数量,等于 array.length / itemSize |
normalized | 是否归一化读取 |
usage | 缓冲用途,默认 StaticDrawUsage,频繁改动时改为 DynamicDrawUsage |
version | 只读,内部版本号,随更新递增 |
needsUpdate | 置为 true 后,下一帧把数据重新上传到 GPU |
方法
| 方法 | 说明 |
|---|---|
getX(i) / getY(i) / getZ(i) / getW(i) | 读取第 i 个顶点的对应分量 |
setX(i, v) / setY / setZ / setW | 写入单个分量,不会自动上传 |
setXYZ(i, x, y, z) | 一次写入三个分量 |
setXYZW(i, x, y, z, w) | 一次写入四个分量,用于颜色 |
getComponent(i, component) | 按分量下标读取,适合循环 |
setComponent(i, component, value) | 按分量下标写入 |
copyAt(i1, attribute, i2) | 把另一个属性的第 i2 个顶点复制到 i1 |
copyArray(array) | 用普通数组覆盖底层缓冲 |
setUsage(usage) | 设置缓冲用途 |
clone() / copy(attr) | 复制属性,底层数组独立 |
示例:手工构建三角形
const positions = new Float32Array([
-1, -1, 0,
1, -1, 0,
0, 1, 0
]);
const colors = new Float32Array([
1, 0.3, 0.2,
0.2, 1, 0.5,
0.3, 0.5, 1
]);
const geometry = new THREE.BufferGeometry();
geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));
geometry.setAttribute('color', new THREE.BufferAttribute(colors, 3));
const material = new THREE.MeshBasicMaterial({ vertexColors: true, side: THREE.DoubleSide });
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
动态修改顶点
const position = geometry.getAttribute('position');
position.setUsage(THREE.DynamicDrawUsage);
function animateWave(t) {
for (let i = 0; i < position.count; i++) {
position.setY(i, Math.sin(t * 0.002 + i * 0.35) * 0.6);
}
position.needsUpdate = true; // 缺少这一行,画面不会变化
}
常见错误
- 数组长度不是
itemSize的整数倍,几何体会被截断,末尾顶点消失。 - 改了数据忘记
needsUpdate = true,GPU 上仍是旧缓冲。 - 用普通
Array而不是 TypedArray,渲染时报类型错误。 - 多个几何体共享同一个属性对象时,改一个会影响所有引用它的网格。
颜色空间要注意。顶点颜色默认按线性空间解释。
从 CSS 或图片取来的 sRGB 颜色,需要先用
THREE.Color.setStyle 再转线性,否则整体偏亮。
经纬志(2026)。《BufferAttribute》。https://www.jingweizhi.com/three/api/buffer-attribute.html(访问日期 2026-11-03)。