经纬志
首页 / luma.gl / API 文档

BufferLayout

先看结论

描述缓冲区内存与着色器属性的对应关系:谁在哪个偏移、用什么格式读、逐顶点还是逐实例。 在 v9 里它是一个类型别名,不是类,也没有构造函数。

最后验证 2026-11-03 · luma.gl 9.4 · 更新 2026-10-28 · 引用本文
type BufferLayout = { name, format?, byteStride?, stepMode?, attributes? }

luma.BufferLayout 在运行期不存在,写 new BufferLayout() 会抛错。 正确做法是给管线或模型的 bufferLayout 传一个对象数组。

字段

字段说明
name缓冲区名,属性名与它同名时可直接映射
format单个属性使用的顶点格式,如 float32x3
stepModevertex 逐顶点步进,instance 逐实例步进
byteStride相邻元素之间的字节跨度,省略时按紧密排列计算
attributes交错布局的成员数组,每项含 attribute、format、byteOffset

一个缓冲区一个属性

最常见的形式:属性名与缓冲区名相同,格式直接写在条目上。 着色器里声明 in vec3 positions,这里就写 float32x3。

const bufferLayout = [
  { name: 'positions', stepMode: 'vertex', format: 'float32x3' },
  { name: 'colors', stepMode: 'vertex', format: 'float32x3' }
];

交错布局

位置、法线、颜色交错在同一段内存里时,用 attributes 描述每个成员的偏移, 再用 byteStride 指明一条记录的长度。偏移与跨度对不上, 画面会整体错位而不报错。

/* 每条记录 32 字节:位置 12 + 法线 12 + 颜色 8 */
const bufferLayout = [
  {
    name: 'vertexData',
    stepMode: 'vertex',
    byteStride: 32,
    attributes: [
      { attribute: 'positions', format: 'float32x3', byteOffset: 0 },
      { attribute: 'normals',   format: 'float32x3', byteOffset: 12 },
      { attribute: 'colors',    format: 'float32x2', byteOffset: 24 }
    ]
  }
];

实例属性

stepMode 设成 instance,每个实例读一条记录, 绘制调用仍然只有一次。省略 stepMode 时 WebGL 后端会按属性名里是否含 instance 推断,显式写出来更稳。

const bufferLayout = [
  { name: 'positions', stepMode: 'vertex', format: 'float32x3' },
  {
    name: 'instanceData',
    stepMode: 'instance',
    byteStride: 16,
    attributes: [
      { attribute: 'instanceOffsets', format: 'float32x3', byteOffset: 0 },
      { attribute: 'instanceOpacity', format: 'float32', byteOffset: 12 }
    ]
  }
];

与 shaderLayout 的分工

回答的问题来源
shaderLayout着色器暴露了哪些属性、位置在哪、类型是什么由着色器源码解析得到
bufferLayout内存里这些属性怎么排布、从哪个缓冲读由应用声明

两者在创建管线与顶点数组时合并使用:管线用它们编译固定状态, device.createVertexArray({ shaderLayout, bufferLayout }) 用它们建立属性绑定。

相关辅助函数

函数作用
getBufferLayoutAttributeNames(bufferLayout)列出布局里声明的全部属性名
getBufferLayoutMinAttributeLocation(bufferLayout)取属性占用的最小位置编号
getLogicalBufferSlots(bufferLayout)取逻辑缓冲区槽位
getShaderAttributeLocationMap(shaderLayout)取属性名到位置编号的映射
getAttributeInfosFromLayouts(shaderLayout, bufferLayout)合并两边的声明,得到每个属性的完整信息

格式字符串必须与着色器类型逐字对应。 float32x2 对 vec2,float32x3 对 vec3, uint8x4 只能对 uvec4 或按归一化声明的输入。 分量数写错时模型不会报错,属性读到的是一片零。

引用本文

经纬志(2026)。《BufferLayout》。https://www.jingweizhi.com/lumagl/api/buffer-layout.html(访问日期 2026-11-03)。