背景
我正在尝试通过直接在 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);
}
回答问题:
A
var<private>
在顶点着色器中是可变的,但仅对当前调用可见。新的
const
关键字是新常量。规范允许删除大部分类型注释,因此按上述方式声明就足够了。
关于webgpu - 如何在 WGSL 顶点着色器中声明和使用 *constant* 数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73379152/