webgpu - 如何在 WGSL 顶点着色器中声明和使用 *constant* 数组?

标签 webgpu

背景

我正在尝试通过直接在 WGSL 顶点着色器中对顶点进行编码来渲染单个三角形。

我的想法是有一个全局常量数组,TRI_VERTICES包含三角形的顶点,我将使用内置 vertex_index 从中查找适当的顶点坐标.

let TRI_VERTICES: array<vec4<f32>, 3> = array<vec4<f32>, 3>(
  vec4<f32>(0., 0., 0., 1.0),
  vec4<f32>(0., 1., 0., 1.0),
  vec4<f32>(1., 1., 0., 1.0),
);

@vertex
fn vs_main(
  @builtin(vertex_index) in_vertex_index: u32,
) -> @builtin(position) vec4<f32> {
  return TRI_VERTICES[in_vertex_index];
}

@fragment
fn fs_main(@builtin(position) in: vec4<f32>) -> @location(0) vec4<f32> {
  return vec4<f32>(in.x, in.y, 0.1, 1.0);
}

我正在使用 3 运行绘制调用(在 Rust 和 wgpu 中)顶点和1实例如下:

render_pass.draw(0..3, 0..1);

不幸的是,我收到以下错误:

Shader validation error:
   ┌─ Shader:13:9
   │
13 │   return TRI_VERTICES[in_vertex_index];
   │         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ naga::Expression [3]


    Entry point vs_main at Vertex is invalid
    Expression [3] is invalid
    The expression [1] may only be indexed by a constant

问题

如果我只更改let TRI_VERTICES,上面的问题似乎很容易解决至var<private> TRI_VERTICES ,但我不确定这是否是“正确”的解决方案。我想知道的是:

  • 是否使用 var<private>意味着数组条目在vs_main内是可变的?
  • 如果是这样,有没有办法声明 TRI_VERTICES以某种方式作为“常数”?
  • 最合适的声明方式是什么 TRI_VERTICES

最佳答案

以下内容在 Tint 中可以正确编译。这可能是 Naga 需要 catch 规范更改的情况,您可以在 https://github.com/gfx-rs/naga 提交 Naga 问题.

const TRI_VERTICES = array(
  vec4(0., 0., 0., 1.),
  vec4(0., 1., 0., 1.),
  vec4(1., 1., 0., 1.),
);

@vertex
fn vs_main(
  @builtin(vertex_index) in_vertex_index: u32,
) -> @builtin(position) vec4<f32> {
  return TRI_VERTICES[in_vertex_index];
}

@fragment
fn fs_main(@builtin(position) in: vec4<f32>) -> @location(0) vec4<f32> {
  return vec4(in.x, in.y, .1, 1);
}

回答问题:

  1. A var<private>在顶点着色器中是可变的,但仅对当前调用可见。

  2. 新的const关键字是新常量。

  3. 规范允许删除大部分类型注释,因此按上述方式声明就足够了。

关于webgpu - 如何在 WGSL 顶点着色器中声明和使用 *constant* 数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73379152/

相关文章:

rust - write_buffer 不写入缓冲区而是输出零 WGPU

batching - 为整个网格而不是每个顶点设置颜色

chrome-canary - 如何让WebGPU在Chrome Canary 97中运行?

typescript - 如何在 WGSL 中使用随机数?