如何将动态值传递到 WGPU 顶点着色器?
How do you pass dynamic values into a WGPU vertex shader?
我是 this wgpu in rust 教程,并且通过像这样定义静态数组成功地在屏幕上渲染了一个三角形:
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] }
];
然后将此数组形成一个名为 vertex_buffer 的 wgpu 缓冲区,然后使用 vertex_buffer 数组将其传递到我的着色器,如下所示:
const ATTRIBS: [wgpu::VertexAttribute; 3] = wgpu::vertex_attr_array![0 => Float32x3, 1 => Float32x3];
. . .
render_pass.set_vertex_buffer(0, self.vertex_buffer.slice(..));
我的问题是:如何让三角形随时间旋转?我最初的方法是创建第二个缓冲区,我也将其传递给着色器,并使用顶点着色器根据输入值调整顶点位置。但是这种方法只给我错误。
具体来说,我正在为每一帧创建一个新缓冲区,其中包含像这样的帧编号
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,
}
);
然后尝试像这样传递它:
render_pass.set_vertex_buffer(1, frame_num.slice(..));
我的着色器现在看起来像这样:
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 {
. . .
我收到的错误是
的变体
Entry point vs_main at Vertex is invalid
Argument 0 varying error
The type [2] does not match the varying
着色器是否设置为接受这样的多个缓冲区?有没有更好的方法来解决这个问题?
继续学习教程 — 您将学到所需的知识。
再过两章,您将到达有关创建相机的部分,该部分将介绍统一缓冲区。统一缓冲区,如顶点缓冲区,是一个 wgpu::Buffer
,但不是用它来定义顶点,它只是可供着色器读取。 (“统一”意味着它不会因顶点或三角形而异——它在整个绘制调用中都是相同的。)
您还需要了解绑定组,这是将统一缓冲区(和纹理)传递给着色器的方法。那是在你正在看的那一章之后和关于设置相机的那一章之前。
我是 this wgpu in rust 教程,并且通过像这样定义静态数组成功地在屏幕上渲染了一个三角形:
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] }
];
然后将此数组形成一个名为 vertex_buffer 的 wgpu 缓冲区,然后使用 vertex_buffer 数组将其传递到我的着色器,如下所示:
const ATTRIBS: [wgpu::VertexAttribute; 3] = wgpu::vertex_attr_array![0 => Float32x3, 1 => Float32x3];
. . .
render_pass.set_vertex_buffer(0, self.vertex_buffer.slice(..));
我的问题是:如何让三角形随时间旋转?我最初的方法是创建第二个缓冲区,我也将其传递给着色器,并使用顶点着色器根据输入值调整顶点位置。但是这种方法只给我错误。
具体来说,我正在为每一帧创建一个新缓冲区,其中包含像这样的帧编号
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,
}
);
然后尝试像这样传递它:
render_pass.set_vertex_buffer(1, frame_num.slice(..));
我的着色器现在看起来像这样:
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 {
. . .
我收到的错误是
的变体Entry point vs_main at Vertex is invalid
Argument 0 varying error
The type [2] does not match the varying
着色器是否设置为接受这样的多个缓冲区?有没有更好的方法来解决这个问题?
继续学习教程 — 您将学到所需的知识。
再过两章,您将到达有关创建相机的部分,该部分将介绍统一缓冲区。统一缓冲区,如顶点缓冲区,是一个 wgpu::Buffer
,但不是用它来定义顶点,它只是可供着色器读取。 (“统一”意味着它不会因顶点或三角形而异——它在整个绘制调用中都是相同的。)
您还需要了解绑定组,这是将统一缓冲区(和纹理)传递给着色器的方法。那是在你正在看的那一章之后和关于设置相机的那一章之前。