WebGPU06-Begin-The Pipeline,来画个可爱的三角形?
作者:互联网
Begin | WebGPU
3.The Pipeline-2
译者注:本节内容紧随上节,是对上节内容的具体应用。
-
怎样使用这些着色器?
在这一部分,我们终于要开始着手于标题内容:the pipeline。
首先我们需要修改
State
来包含以下代码:// main.rs struct State { surface: wgpu::Surface, device: wgpu::Device, queue: wgpu::Queue, config: wgpu::SurfaceConfiguration, size: winit::dpi::PhysicalSize<u32>, // NEW! render_pipeline: wgpu::RenderPipeline, }
现在让我们将目光移向 方法部分,开始完善
pipeline
。由于
render_pipeline
需要这些,我们要将下列代码写入我们之前创建的着色器:let shader = device.create_shader_module(&wgpu::ShaderModuleDescriptor { label: Some("Shader"), source: wgpu::ShaderSource::Wgsl(include_str!("shader.wgsl").into()), });
此处不译,但需查看
You can also use
include_wgsl!
macro as a small shortcut to create theShaderModuleDescriptor
.let shader = device.create_shader_module(&include_wgsl!("shader.wgsl"));
还有一件事,我们需要创建一个名为
PipelineLayout
的方法。在我们介绍
Buffers
后,我们将对此作更多介绍:let render_pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { label: Some("Render Pipeline Layout"), bind_group_layouts: &[], push_constant_ranges: &[], });
终于,我们有了我们需要用来创建
render_pipeline
的一切:1.render_pipeline-1
let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { label: Some("Render Pipeline"), layout: Some(&render_pipeline_layout), vertex: wgpu::VertexState { module: &shader, entry_point: "vs_main", // 1. buffers: &[], // 2. }, fragment: Some(wgpu::FragmentState { // 3. module: &shader, entry_point: "fs_main", targets: &[wgpu::ColorTargetState { // 4. format: config.format, blend: Some(wgpu::BlendState::REPLACE), write_mask: wgpu::ColorWrites::ALL, }], }), // continued ...
代码讲解:
在这有几件事需要注意:
-
这里在着色器中你能够指定的函数应当是
entry_point
。这些函数是我们用
[[stage(vertex)]]
和[[stage(fragment)]]
标记过的。 -
buffers
区 告诉wgpu
我们想传递各种类型的顶点给顶点着色器。由于我们要在 顶点着色器 中指定其本身的 顶点,所以我们将 顶点着色器 设置为空。在下个指导中,我们会像其中添加一些代码。 -
该
fragment
是技术性可选的,所以你得将其包入Some()
中。如果我们想将颜色数据存入surface
中,我们就需要它。 -
targets
域告诉wgpu
它应该设置什么样的颜色输出。通常,我们仅需其中一个用于surface
。我们使用surface
的格式,以便轻松复制到它中,并且我们指定 混合(blending) 应该只用新数据替换旧像素数据。我们同时也告诉
wgpu
写入所有颜色:red,blue,green,还有alpha。在我们讨论材质时,我们对color_state
会作更深入的了解。
2.render_pipeline-2
primitive: wgpu::PrimitiveState { topology: wgpu::PrimitiveTopology::TriangleList, // 1. strip_index_format: None, front_face: wgpu::FrontFace::Ccw, // 2. cull_mode: Some(wgpu::Face::Back), // Setting this to anything other than Fill requires Features::NON_FILL_POLYGON_MODE polygon_mode: wgpu::PolygonMode::Fill, // Requires Features::DEPTH_CLIP_CONTROL unclipped_depth: false, // Requires Features::CONSERVATIVE_RASTERIZATION conservative: false, }, // continued ...
代码讲解:
primitive
域 描述了怎样解释我们的顶点当将它们转换为三角形时:-
使用
PrimitiveTopology::TriangleList
意味着每三个顶点将与一个三角形建立联系。 -
front_face
与cull_mode
域 告诉wgpu
如何决定一个给定的三角形是否面向前方。FrontFce::Ccw
意味着如果 顶点 由 逆时针方向(counter-clockwise direction)安排三角形面向前方。按照
CullMode::Back
的指定,不被视为面前前方的三角形将会被剔除(cull:not included in the render)。在我们介绍
Buffer
时,我们再对 剔除(cull)作更多介绍。
3.render_pipeline-3
depth_stencil: None, // 1. multisample: wgpu::MultisampleState { count: 1, // 2. mask: !0, // 3. alpha_to_coverage_enabled: false, // 4. }, multiview: None, // 5. });
代码讲解:
此方法的剩余部分十分简单:
- 目前我们没有使用 深度/模板(depth/stencil) 缓冲区,所以我们先将
depth_stencil
设置为None
。我们待会儿再来修改它。 count
决定了 管道 将使用多少个 采样(sample)。多重采样是一个复杂的话题,所以我们不在此讨论。mask
指定了那些 采样 应该被使用。在此处我们全部使用。alpha_to_coverage_enabled
与 抗锯齿 有关。此处并不包括 抗锯齿,所以我们目前在此设置为false
。multiview(多视图)
指示 渲染附件(render attachment)可以具有多少个 数组层(array layer)。我们不会渲染至 数组纹理(array texture),因此我们可以将其设置为None
。
现在我们所需要做的仅是将
render_pipeline
添加至State
中,然后我们就可以使用它了!Self { surface, device, queue, config, size, // NEW! render_pipeline, }
-
-
使用一个 管道:Using a pipeline
如果你现在运行你的程序,程序启动会花费更多时间,但最后它仍会显示我们在上一节中得到的蓝色屏幕。这是因为当我们创建了
render_pipeline
时,我们需要修改render()
中的代码来实际使用它。// render() // ... { // 1. let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { label: Some("Render Pass"), color_attachments: &[ // This is what [[location(0)]] in the fragment shader targets wgpu::RenderPassColorAttachment { view: &view, resolve_target: None, ops: wgpu::Operations { load: wgpu::LoadOp::Clear( wgpu::Color { r: 0.1, g: 0.2, b: 0.3, a: 1.0, } ), store: true, } } ], depth_stencil_attachment: None, }); // NEW! render_pass.set_pipeline(&self.render_pipeline); // 2. render_pass.draw(0..3, 0..1); // 3. } // ...
我们并未做太多的修改,但还是让我们具体讨论一下我们修改了什么:
- 我们重命名
_render_pass
为render_pass
并使它可变。 - 我们使用刚刚创建的 管道 在
render_pass
上来设置 管道。(?) - 我们告知
wgpu
用3个 顶点 和1个 采样 来绘制一些东西。这就是[[builein(vertex_index)]]
的来源。
当所有工作都完成时,运行代码,你将得到一个可爱(大嘘)的棕色三角形。
- 我们重命名
-
Challenge:挑战
此处不译,自行尝试。
Create a second pipeline that uses the triangle's position data to create a color that it then sends to the fragment shader. Have the app swap between these when you press the spacebar.
Hint: you'll need to modify
VertexOutput
该博客由本人个人翻译自Learn Wgpu,因此可能有部分文本不易理解或出现错误,如有发现还望告知,本人必定及时更改。
标签:pipeline,render,Some,WebGPU06,shader,wgpu,画个,Pipeline,我们 来源: https://www.cnblogs.com/microwang/p/16122759.html