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
9#[cfg(feature = "selector")]
10use super::{entity_id_pass::EntityIdPass, outline_pass::OutlinePass};
11use super::{line_pipeline::LinePipeline, mesh_pipeline::MeshPipeline, point_pipeline::PointPipeline, upload_pass::PerFrameUniforms};
12
13use crate::forward_renderer::{render_passes::pipeline_runner::PipelineRunner, renderer::OffscreenTarget};
14use easy_wgpu::framebuffer::FrameBuffer;
15
16pub struct MainPass {
18 mesh_pipeline: MeshPipeline,
19 point_pipeline: PointPipeline,
20 line_pipeline: LinePipeline,
21 #[cfg(feature = "selector")]
22 outline_pass: OutlinePass,
23 #[cfg(feature = "selector")]
24 entity_id_pass: EntityIdPass,
25}
26
27impl MainPass {
28 pub fn new(gpu: &Gpu, params: &RenderConfig, color_target_format: wgpu::TextureFormat, depth_target_format: wgpu::TextureFormat) -> Self {
29 let mesh_pipeline = MeshPipeline::new(gpu, params, color_target_format, depth_target_format);
30 let point_pipeline = PointPipeline::new(gpu, params, color_target_format, depth_target_format);
31 let line_pipeline = LinePipeline::new(gpu, params, color_target_format, depth_target_format);
32 #[cfg(feature = "selector")]
33 let outline_pass = OutlinePass::new(gpu, params, color_target_format, depth_target_format);
34 #[cfg(feature = "selector")]
35 let entity_id_pass = EntityIdPass::new(gpu);
36 Self {
37 mesh_pipeline,
38 point_pipeline,
39 line_pipeline,
40 #[cfg(feature = "selector")]
41 outline_pass,
42 #[cfg(feature = "selector")]
43 entity_id_pass,
44 }
45 }
46
47 #[allow(clippy::too_many_lines)]
51 pub fn run(
52 &mut self,
53 gpu: &Gpu,
54 per_frame_uniforms: &PerFrameUniforms,
55 offscreen_fb: &FrameBuffer<OffscreenTarget>,
56 out_view: &wgpu::TextureView,
57 scene: &mut Scene,
58 render_params: &RenderConfig,
59 ) {
60 self.begin_pass();
61
62 let aces = gloss_utils::tonemap::AcesFitted::new();
64 let bg_color_vec = render_params.bg_color.fixed_rows::<3>(0).clone_owned();
65 let bg_color_tonemapped = aces.tonemap(&bg_color_vec);
66 let bg_color_tonemapped_gamma = na::Vector3::from_iterator(bg_color_tonemapped.iter().map(|x| x.powf(1.0 / 2.2)));
67
68 let mut line_query = self.line_pipeline.prepare(gpu, per_frame_uniforms, scene);
73 let mut mesh_query = self.mesh_pipeline.prepare(gpu, per_frame_uniforms, scene);
74 let mut point_query = self.point_pipeline.prepare(gpu, per_frame_uniforms, scene);
75 #[cfg(feature = "selector")]
76 let mut outline_query = self.outline_pass.prepare(gpu, per_frame_uniforms, scene);
77 #[cfg(feature = "selector")]
78 let mut entity_id_query = self.entity_id_pass.prepare(gpu, per_frame_uniforms, scene);
79 let mut encoder = gpu.device().create_command_encoder(&wgpu::CommandEncoderDescriptor {
81 label: Some("MainPass Encoder"),
82 });
83 {
84 let color_clear_op = wgpu::LoadOp::Clear(wgpu::Color {
86 r: f64::from(bg_color_tonemapped_gamma.x),
87 g: f64::from(bg_color_tonemapped_gamma.y),
88 b: f64::from(bg_color_tonemapped_gamma.z),
89 a: f64::from(render_params.bg_color.w),
90 });
91
92 let mut selected_out_view = out_view;
93 let mut store = wgpu::StoreOp::Store;
94 let mut resolve_target = None;
95
96 if render_params.msaa_nr_samples > 1 {
97 resolve_target = Some(out_view);
98 selected_out_view = &offscreen_fb.get(OffscreenTarget::MSAAColor).unwrap().view;
99 store = wgpu::StoreOp::Discard; }
104 {
106 let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
107 label: Some("Main Pass"),
108 color_attachments: &[Some(wgpu::RenderPassColorAttachment {
109 view: selected_out_view,
110 resolve_target,
111 ops: wgpu::Operations { load: color_clear_op, store },
112 })],
113 depth_stencil_attachment: Some(wgpu::RenderPassDepthStencilAttachment {
114 view: &offscreen_fb.get(OffscreenTarget::Depth).unwrap().view,
115 depth_ops: Some(wgpu::Operations {
116 load: wgpu::LoadOp::Clear(0.0),
117 store,
118 }),
119 stencil_ops: Some(wgpu::Operations {
120 load: wgpu::LoadOp::Clear(0),
121 store: wgpu::StoreOp::Store,
122 }),
123 }),
124 timestamp_writes: None,
125 occlusion_query_set: None,
126 });
127 self.mesh_pipeline
128 .run(&mut render_pass, per_frame_uniforms, render_params, &mut mesh_query, scene);
129 self.point_pipeline
130 .run(&mut render_pass, per_frame_uniforms, render_params, &mut point_query, scene);
131 self.line_pipeline
132 .run(&mut render_pass, per_frame_uniforms, render_params, &mut line_query, scene);
133 #[cfg(feature = "selector")]
135 self.outline_pass
136 .run(&mut render_pass, per_frame_uniforms, render_params, &mut outline_query, scene);
137 }
138
139 #[cfg(feature = "selector")]
141 if let Some(camera) = scene.get_current_cam() {
142 if camera.is_click(scene) {
143 let mut entity_id_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
144 label: Some("Entity ID Pass"),
145 color_attachments: &[Some(wgpu::RenderPassColorAttachment {
146 view: &offscreen_fb.get(OffscreenTarget::EntityID).unwrap().view,
147 resolve_target: None,
148 ops: wgpu::Operations {
149 load: wgpu::LoadOp::Clear(wgpu::Color::TRANSPARENT),
150 store: wgpu::StoreOp::Store,
151 },
152 })],
153 depth_stencil_attachment: Some(wgpu::RenderPassDepthStencilAttachment {
154 view: &offscreen_fb.get(OffscreenTarget::SingleDepth).unwrap().view,
155 depth_ops: Some(wgpu::Operations {
156 load: wgpu::LoadOp::Clear(0.0),
157 store: wgpu::StoreOp::Discard,
158 }),
159 stencil_ops: Some(wgpu::Operations {
160 load: wgpu::LoadOp::Load,
161 store: wgpu::StoreOp::Discard,
162 }),
163 }),
164 timestamp_writes: None,
165 occlusion_query_set: None,
166 });
167 self.entity_id_pass
168 .run(&mut entity_id_pass, per_frame_uniforms, render_params, &mut entity_id_query, scene);
169 }
170 }
171 }
172 gpu.queue().submit(Some(encoder.finish()));
173
174 self.end_pass();
175 }
176
177 fn begin_pass(&mut self) {
178 trace!("begin main_pass");
179 }
180
181 fn end_pass(&mut self) {
182 trace!("end main_pass");
183 }
184}