我只是嘗試將頂點位置陣列傳送到頂點著色器。
這是我的 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 位元組。
您將
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>