I'm trying to render a single triangle by encoding the vertices directly in my WGSL vertex shader.
My idea was to have a global constant array, TRI_VERTICES
contain the vertices of the triangle, from which I will look up the appropriate vertex coordinates using the builtin 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);
}
I am running a draw call (in Rust and wgpu) using 3
vertices and 1
instance as follows:
render_pass.draw(0..3, 0..1);
Unfortunately, I get the following error:
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
The above seems easily fixed if I just change let TRI_VERTICES
to var<private> TRI_VERTICES
, but I'm not sure if this is the "correct" solution. What I would like to know is:
var<private>
mean that the array entries are mutable within vs_main
?TRI_VERTICES
as "constant" somehow?TRI_VERTICES
?The following compiles correctly in Tint. This maybe a case of Naga needing to catchup to spec changes, you can file Naga issues at https://github.com/gfx-rs/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);
}
To answer the questions:
A var<private>
is mutable in the vertex shader but only visible to the current invocation.
The new const
keyword is the new constant.
The spec allows dropping most of the type annotations, so declaring as above should be sufficient.