gloss_renderer/forward_renderer/render_passes/
main_pass.rs1use crate::config::RenderConfig;
2use log::trace;
3use nalgebra as na;
4
5use crate::scene::Scene;
6
7use easy_wgpu::gpu::Gpu;
8
9use super::{line_pipeline::LinePipeline, mesh_pipeline::MeshPipeline, point_pipeline::PointPipeline, upload_pass::PerFrameUniforms};
10
11use crate::forward_renderer::{render_passes::pipeline_runner::PipelineRunner, renderer::OffscreenTarget};
12use easy_wgpu::framebuffer::FrameBuffer;
13
14pub struct MainPass {
16 mesh_pipeline: MeshPipeline,
17 point_pipeline: PointPipeline,
18 line_pipeline: LinePipeline,
19}
20
21impl MainPass {
22 pub fn new(gpu: &Gpu, params: &RenderConfig, color_target_format: wgpu::TextureFormat, depth_target_format: wgpu::TextureFormat) -> Self {
23 let mesh_pipeline = MeshPipeline::new(gpu, params, color_target_format, depth_target_format);
24 let point_pipeline = PointPipeline::new(gpu, params, color_target_format, depth_target_format);
25 let line_pipeline = LinePipeline::new(gpu, params, color_target_format, depth_target_format);
26 Self {
27 mesh_pipeline,
28 point_pipeline,
29 line_pipeline,
30 }
31 }
32
33 #[allow(clippy::too_many_lines)]
37 pub fn run(
38 &mut self,
39 gpu: &Gpu,
40 per_frame_uniforms: &PerFrameUniforms,
41 offscreen_fb: &FrameBuffer<OffscreenTarget>,
42 out_view: &wgpu::TextureView,
43 scene: &mut Scene,
44 render_params: &RenderConfig,
45 ) {
46 self.begin_pass();
47
48 let aces = gloss_utils::tonemap::AcesFitted::new();
50 let bg_color_vec = render_params.bg_color.fixed_rows::<3>(0).clone_owned();
51 let bg_color_tonemapped = aces.tonemap(&bg_color_vec);
52 let bg_color_tonemapped_gamma = na::Vector3::from_iterator(bg_color_tonemapped.iter().map(|x| x.powf(1.0 / 2.2)));
53
54 let mut line_query = self.line_pipeline.prepare(gpu, per_frame_uniforms, scene);
59 let mut mesh_query = self.mesh_pipeline.prepare(gpu, per_frame_uniforms, scene);
60 let mut point_query = self.point_pipeline.prepare(gpu, per_frame_uniforms, scene);
61
62 let mut encoder = gpu.device().create_command_encoder(&wgpu::CommandEncoderDescriptor {
64 label: Some("MainPass Encoder"),
65 });
66 {
67 let color_clear_op = wgpu::LoadOp::Clear(wgpu::Color {
69 r: f64::from(bg_color_tonemapped_gamma.x),
70 g: f64::from(bg_color_tonemapped_gamma.y),
71 b: f64::from(bg_color_tonemapped_gamma.z),
72 a: f64::from(render_params.bg_color.w),
73 });
74
75 let mut selected_out_view = out_view;
76 let mut store = wgpu::StoreOp::Store;
77 let mut resolve_target = None;
78
79 if render_params.msaa_nr_samples > 1 {
80 resolve_target = Some(out_view);
81 selected_out_view = &offscreen_fb.get(OffscreenTarget::MSAAColor).unwrap().view;
82 store = wgpu::StoreOp::Discard; }
87
88 let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
89 label: Some("Main Pass"),
90 color_attachments: &[
91 Some(wgpu::RenderPassColorAttachment {
93 view: selected_out_view,
94 resolve_target,
95 ops: wgpu::Operations { load: color_clear_op, store },
96 }),
97 ],
98 depth_stencil_attachment: Some(wgpu::RenderPassDepthStencilAttachment {
99 view: &offscreen_fb.get(OffscreenTarget::Depth).unwrap().view,
100 depth_ops: Some(wgpu::Operations {
101 load: wgpu::LoadOp::Clear(0.0),
102 store,
103 }),
104 stencil_ops: None,
105 }),
106 timestamp_writes: None,
107 occlusion_query_set: None,
108 });
109
110 self.mesh_pipeline
112 .run(&mut render_pass, per_frame_uniforms, render_params, &mut mesh_query);
113
114 self.point_pipeline
115 .run(&mut render_pass, per_frame_uniforms, render_params, &mut point_query);
116 self.line_pipeline
117 .run(&mut render_pass, per_frame_uniforms, render_params, &mut line_query);
118 }
119 gpu.queue().submit(Some(encoder.finish()));
120
121 self.end_pass();
122 }
123
124 fn begin_pass(&mut self) {
125 trace!("begin main_pass");
126 }
127
128 fn end_pass(&mut self) {
129 trace!("end main_pass");
130 }
131}