首頁  >  問答  >  主體

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 天前328

全部回覆(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
  • 取消回覆