WebGPU顶点范围报错:所需缓冲区大于绑定缓冲区大小
WebGPU顶点缓冲区大小不匹配问题排查与解决
报错信息:
Vertex range (first: 0, count: 12) requires a larger buffer (192) than the bound buffer size (48) of the vertex buffer at slot 0 with stride 16. - While encoding [RenderPassEncoder].Draw(12, 1, 0, 0)
我的情况:JS里的Float32Array长度为12(对应48字节),但WebGPU提示需要192字节;将缓冲区大小改为368字节能正常渲染三角形,低于此值就失败,且增加顶点数据后所需缓冲区大小会翻倍。
相关代码片段
JavaScript代码
const vertices = new Float32Array([0, 0.5, 0, 1, -0.5, -0.5, 0, 2, 0.5, -0.5, 0, 1]); const vertexBuffer = device.createBuffer({ // equal to 48 size: vertices.byteLength, usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST, }); device.queue.writeBuffer(vertexBuffer, 0, vertices); const vertexBuffers = [ { attributes: [ { shaderLocation: 0, offset: 0, format: "float32x4", }, ], arrayStride: 16, stepMode: "vertex", }, ];
WGSL着色器代码
@vertex fn vMain(@location(0) vertexPosition: vec4<f32>, @builtin(vertex_index) vertexIndex: u32) -> @builtin(position) vec4<f32> { var positions = array<vec4<f32>, 3>( vec4<f32>(0, 0.5, 0, 1), vec4<f32>(-0.5, -0.5, 0, 2), vec4<f32>(0.5, -0.5, 0, 1), ); return positions[vertexIndex]; } @fragment fn fMain() -> @location(0) vec4<f32> { return vec4<f32>(1, 1, 1, 1); }
问题原因
核心矛盾在于渲染管线配置和实际渲染调用不匹配:
- 绑定了顶点缓冲区且设置每个顶点步长为16字节,WebGPU会认为每个顶点需要读取16字节数据。
- 调用
Draw(12, 1, 0, 0)意味着要渲染12个顶点,WebGPU会尝试读取12 * 16 = 192字节数据,但缓冲区仅48字节,触发报错。 - 着色器根本没用到JS传递的顶点数据,而是通过内部数组+
vertex_index获取位置,但绑定的顶点缓冲区依然会被管线尝试读取。
解决方法
方法一:移除不必要的顶点缓冲区绑定
既然着色器内部已定义顶点数据,不需要从JS传递,直接删除顶点缓冲区的创建、写入和绑定代码,渲染时就不会再尝试读取缓冲区,报错消失。
方法二:匹配顶点缓冲区与渲染调用
如果确实需要从JS传递顶点数据:
- 修改Draw调用的count参数为3(实际只有3个顶点),即
Draw(3, 1, 0, 0)。 - 此时所需缓冲区大小为
3 * 16 = 48字节,和当前缓冲区大小匹配,报错会消失。 - 同时可以修改着色器,使用传入的
vertexPosition参数,比如把返回值改成vertexPosition,真正用上JS传递的顶点数据。
内容的提问来源于stack exchange,提问作者luek baja
相关产品推荐
相关产品推荐

