首页  >  问答  >  正文

WebGPU:顶点范围要求的缓冲区大小大于绑定缓冲区大小

我只是尝试将顶点位置数组发送到顶点着色器。

这是我的 JS 代码片段:

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",
    },
];

Float32Array 的长度为 12,因此为 48 个字节。但是,我收到此错误消息,指出我需要 192 字节:

顶点范围(第一个:0,计数:12)需要比插槽 0 处的顶点缓冲区的绑定缓冲区大小 (48) 更大的缓冲区 (192),步长为 16。 - 编码 [RenderPassEncoder].Draw(12 时, 1, 0, 0)。

这可能与问题无关,但对于上下文,这是我的着色器程序:

@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);
}

它不使用顶点数组,但我仅使用它来显示一切运行是否没有错误。当我将代码片段第 3 行的缓冲区大小从 vertices.byteLength 更改为 368 时,它可以正常运行并呈现一个三角形。任何低于 368 的值都会导致失败。

经过进一步测试,我发现通过在每个顶点添加 4 个浮点并将步长更改为 32 将 Float32Array 的大小加倍,将导致 WebGPU 声明我需要 768 字节。

P粉282627613P粉282627613204 天前329

全部回复(1)我来回复

  • P粉676821490

    P粉6768214902024-03-30 12:13:07

    您将 arrayStride 设置为 32,这意味着每个顶点将占用 32 个字节(https://developer.mozilla.org/en-US/docs/Web/API/WebGPU_API#define_and_create_the_render_pipeline)。

    从你的顶点布局来看,这应该是 16,因为你只定义了一种格式 float32x4 = 16 字节。

    从错误消息 (Draw(12, 1, 0, 0)) 来看,您似乎正在尝试绘制 12 个顶点。这意味着预期的总缓冲区大小为:12*32 = 368。根据您的格式,这可能应该是 Draw(3, 1, 0, 0) 。这样你的 vertexBuffer 就可以被分割成 3 个顶点,每个顶点的位置值为 vec4<f32>

    回复
    0
  • 取消回复