How do you pass dynamic values into a WGPU vertex shader?

1.9k Views Asked by At

I am this tutorial for wgpu in rust and have successfully rendered a triangle on screen by defining a static array like this:

const VERTICES: &[Vertex] = &[
    Vertex { position: [-0.0868241, 0.49240386, 0.0], color: [0.1, 0.0, 0.5] }, 
    Vertex { position: [-0.49513406, 0.06958647, 0.0], color: [0.5, 0.0, 0.9] }, 
    Vertex { position: [-0.21918549, -0.44939706, 0.0], color: [0.5, 0.0, 0.5] } 
];

This array is then formed into a wgpu buffer called vertex_buffer and then a passing it to my shader with a vertex_buffer array like so:

const ATTRIBS: [wgpu::VertexAttribute; 3] = wgpu::vertex_attr_array![0 => Float32x3, 1 => Float32x3]; 

. . . 

render_pass.set_vertex_buffer(0, self.vertex_buffer.slice(..));

This My question is this: How would I have the triangle rotate over time? My initial approach was to create a second buffer that I pass to the shader as well and use a vertex shader to adjust the vertex positions basted on the input value. But this approach gives me nothing but errors.

Specifically I am creating a new buffer every frame which contains the frame number like so

let frame_num = self.device.create_buffer_init(
            &wgpu::util::BufferInitDescriptor {
                label: Some("Control Num Buffer"),
                contents: bytemuck::cast_slice(&[
                    self.frame_num,
                    self.frame_num,
                    self.frame_num
                ]),
                usage: wgpu::BufferUsages::VERTEX,
            }
        );

and then trying to pass it in like this:

render_pass.set_vertex_buffer(1, frame_num.slice(..));

with my shader now looking like this:

struct VertexInput {
    [[location(0)]] position: vec3<f32>;
    [[location(1)]] color: vec3<f32>
};

struct VertexOutput {
    [[builtin(position)]] clip_position: vec4<f32>;
    [[location(0)]] color: vec3<f32>;
};

[[stage(vertex)]]
fn vs_main( 
    
    [[location(0)]] model: VertexInput, 
    [[location(1)]] numb : f32 ) 
    
    -> VertexOutput {

        . . .

I am getting errors that are variants of

Entry point vs_main at Vertex is invalid
Argument 0 varying error
The type [2] does not match the varying

Are shaders setup to accept multiple buffers like this? Is there better ways to go about this?

1

There are 1 best solutions below

0
On BEST ANSWER

Keep going in the tutorial — you'll learn what you need.

Two chapters from where you are, you will reach the section on creating a camera, which will introduce uniform buffers. A uniform buffer, like a vertex buffer, is a wgpu::Buffer, but instead of using it to define vertices, it just becomes available for the shader to read. (“Uniform” means that it doesn't vary per vertex or per triangle — it's the same across the whole draw call.)

You'll also need to learn about bind groups which are the means by which uniform buffers (and textures) are passed to the shader. That's in the chapter after the one you're on and before the one on setting up a camera.