我只是尝试将顶点位置数组发送到顶点着色器。
这是我的 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粉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>