From eaefcff45fec1042663d9b7669f97f53919be01a Mon Sep 17 00:00:00 2001 From: Paris DOUADY Date: Wed, 21 Feb 2024 11:47:36 +0100 Subject: [PATCH] allow configuring MSAA --- assets/shaders/fog.wgsl | 4 ++ assets/shaders/ssao.wgsl | 5 ++ assets/shaders/water.frag.wgsl | 4 ++ engine/src/drawables/lit_mesh.rs | 5 +- engine/src/gfx.rs | 59 ++++++++++++++----- engine/src/passes/background.rs | 28 ++++++--- engine/src/pipelines.rs | 10 ++-- engine/src/yakui.rs | 23 ++++++-- native_app/src/newgui/hud/windows/settings.rs | 5 ++ 9 files changed, 108 insertions(+), 35 deletions(-) diff --git a/assets/shaders/fog.wgsl b/assets/shaders/fog.wgsl index af6abf7e..7b0d4b06 100644 --- a/assets/shaders/fog.wgsl +++ b/assets/shaders/fog.wgsl @@ -18,7 +18,11 @@ struct FragmentOutput { @group(0) @binding(0) var params: RenderParams; +#ifdef MSAA @group(1) @binding(0) var t_depth: texture_multisampled_2d; +#else +@group(1) @binding(0) var t_depth: texture_2d; +#endif @group(1) @binding(1) var s_depth: sampler; fn uv2s(uv: vec2) -> vec2 { diff --git a/assets/shaders/ssao.wgsl b/assets/shaders/ssao.wgsl index f2759627..a6287ae0 100644 --- a/assets/shaders/ssao.wgsl +++ b/assets/shaders/ssao.wgsl @@ -17,7 +17,12 @@ struct FragmentOutput { @group(0) @binding(0) var params: RenderParams; +#ifdef MSAA @group(1) @binding(0) var t_depth: texture_multisampled_2d; +#else +@group(1) @binding(0) var t_depth: texture_2d; +#endif + @group(1) @binding(1) var s_depth: sampler; diff --git a/assets/shaders/water.frag.wgsl b/assets/shaders/water.frag.wgsl index 8fcee99b..190302bb 100644 --- a/assets/shaders/water.frag.wgsl +++ b/assets/shaders/water.frag.wgsl @@ -8,7 +8,11 @@ struct FragmentOutput { @group(0) @binding(0) var params: RenderParams; +#ifdef MSAA @group(1) @binding(0) var t_depth: texture_multisampled_2d; +#else +@group(1) @binding(0) var t_depth: texture_2d; +#endif @group(1) @binding(1) var s_depth: sampler; @group(2) @binding(0) var t_wavy: texture_2d; diff --git a/engine/src/drawables/lit_mesh.rs b/engine/src/drawables/lit_mesh.rs index bbd04a17..7a101346 100644 --- a/engine/src/drawables/lit_mesh.rs +++ b/engine/src/drawables/lit_mesh.rs @@ -99,7 +99,10 @@ impl PipelineKey for MeshPipeline { false => gfx.sc_desc.format, }, ) - .with_samples(gfx.samples); + .with_samples(match self.offscreen_render { + true => 4, + false => gfx.samples, + }); if self.offscreen_render { builder = builder.with_depth_write(); diff --git a/engine/src/gfx.rs b/engine/src/gfx.rs index 511d923b..5dcfe392 100644 --- a/engine/src/gfx.rs +++ b/engine/src/gfx.rs @@ -145,6 +145,7 @@ pub struct GfxSettings { pub pbr_enabled: bool, pub fog_shader_debug: bool, pub parallel_render: bool, + pub msaa: bool, } impl Default for GfxSettings { @@ -160,6 +161,7 @@ impl Default for GfxSettings { pbr_enabled: true, fog_shader_debug: false, parallel_render: false, + msaa: false, } } } @@ -314,7 +316,8 @@ impl GfxContext { alpha_mode: CompositeAlphaMode::Auto, view_formats: vec![], }; - let samples = if cfg!(target_arch = "wasm32") { 1 } else { 4 }; + // let samples = if cfg!(target_arch = "wasm32") { 1 } else { 4 }; + let samples = 1; let fbos = Self::create_textures(&device, &sc_desc, samples); surface.configure(&device, &sc_desc); @@ -611,12 +614,25 @@ impl GfxContext { } } + let samples = match settings.msaa { + true => 4, + false => 1, + }; + + if self.samples != samples { + self.samples = samples; + self.pipelines.write().unwrap().invalidate_all(); + self.fbos = Self::create_textures(&self.device, &self.sc_desc, samples); + self.update_simplelit_bg(); + } + self.set_define_flag("FOG", settings.fog); self.set_define_flag("SSAO", settings.ssao); self.set_define_flag("TERRAIN_GRID", settings.terrain_grid); self.set_define_flag("DEBUG", settings.shader_debug); self.set_define_flag("FOG_DEBUG", settings.fog_shader_debug); self.set_define_flag("PBR_ENABLED", settings.pbr_enabled); + self.set_define_flag("MSAA", settings.msaa); self.settings = Some(settings); } @@ -789,19 +805,31 @@ impl GfxContext { let mut main_enc = self .device .create_command_encoder(&CommandEncoderDescriptor { - label: Some("shadow map encoder"), + label: Some("main pass encoder"), }); - let mut render_pass = main_enc.begin_render_pass(&RenderPassDescriptor { - label: Some("main render pass"), - color_attachments: &[Some(RenderPassColorAttachment { + let ops = wgpu::Operations { + load: wgpu::LoadOp::Clear(wgpu::Color::TRANSPARENT), + store: wgpu::StoreOp::Store, + }; + + let attachment = if self.samples > 1 { + RenderPassColorAttachment { view: &self.fbos.color_msaa, resolve_target: Some(frame), - ops: wgpu::Operations { - load: wgpu::LoadOp::Clear(wgpu::Color::TRANSPARENT), - store: wgpu::StoreOp::Store, - }, - })], + ops, + } + } else { + RenderPassColorAttachment { + view: frame, + resolve_target: None, + ops, + } + }; + + let mut render_pass = main_enc.begin_render_pass(&RenderPassDescriptor { + label: Some("main render pass"), + color_attachments: &[Some(attachment)], depth_stencil_attachment: Some(wgpu::RenderPassDepthStencilAttachment { view: &self.fbos.depth.view, depth_ops: None, @@ -927,10 +955,7 @@ impl GfxContext { ); if self.defines_changed { self.defines_changed = false; - self.pipelines - .write() - .unwrap() - .invalidate_all(&self.defines, &self.device); + self.pipelines.write().unwrap().invalidate_all(); } if self.tick % 30 == 0 { #[cfg(debug_assertions)] @@ -977,7 +1002,11 @@ impl GfxContext { FBOs { depth, depth_bg, - color_msaa: Texture::create_color_msaa(device, desc, samples), + color_msaa: if samples > 1 { + Texture::create_color_msaa(device, desc, samples) + } else { + ssao.mip_view(0) // bogus + }, ssao, fog, ui_blur, diff --git a/engine/src/passes/background.rs b/engine/src/passes/background.rs index f7da5ce0..b592a42b 100644 --- a/engine/src/passes/background.rs +++ b/engine/src/passes/background.rs @@ -10,16 +10,28 @@ use wgpu::{ pub fn render_background(gfx: &GfxContext, enc: &mut CommandEncoder, frame: &TextureView) { profiling::scope!("bg pass"); - let mut bg_pass = enc.begin_render_pass(&RenderPassDescriptor { - label: Some("bg pass"), - color_attachments: &[Some(RenderPassColorAttachment { + let ops = wgpu::Operations { + load: wgpu::LoadOp::Load, // Don't clear! We're drawing after main pass + store: wgpu::StoreOp::Store, + }; + + let attachment = if gfx.samples > 1 { + RenderPassColorAttachment { view: &gfx.fbos.color_msaa, resolve_target: Some(frame), - ops: wgpu::Operations { - load: wgpu::LoadOp::Load, - store: wgpu::StoreOp::Store, - }, - })], + ops, + } + } else { + RenderPassColorAttachment { + view: frame, + resolve_target: None, + ops, + } + }; + + let mut bg_pass = enc.begin_render_pass(&RenderPassDescriptor { + label: Some("bg pass"), + color_attachments: &[Some(attachment)], depth_stencil_attachment: Some(wgpu::RenderPassDepthStencilAttachment { view: &gfx.fbos.depth.view, depth_ops: Some(wgpu::Operations { diff --git a/engine/src/pipelines.rs b/engine/src/pipelines.rs index 2b7ac7c2..8ebfe14d 100644 --- a/engine/src/pipelines.rs +++ b/engine/src/pipelines.rs @@ -113,11 +113,11 @@ impl Pipelines { } } - pub fn invalidate_all(&mut self, defines: &FastMap, device: &Device) { - let shader_names = self.shader_watcher.keys().cloned().collect::>(); - for shader_name in shader_names { - self.invalidate(defines, device, &shader_name); - } + pub fn invalidate_all(&mut self) { + self.pipelines.clear(); + self.shader_watcher.clear(); + self.shader_cache.clear(); + self.pipelines_deps.clear(); } pub fn invalidate( diff --git a/engine/src/yakui.rs b/engine/src/yakui.rs index 228a930c..e858b9f1 100644 --- a/engine/src/yakui.rs +++ b/engine/src/yakui.rs @@ -82,17 +82,28 @@ impl YakuiWrapper { self.yakui.finish(); } - self.renderer.paint_with_encoder( - &mut self.yakui, - &gfx.gfx.device, - &gfx.gfx.queue, - gfx.encoder, + let surface_info = if gfx.gfx.samples > 1 { yakui_wgpu::SurfaceInfo { format: self.format, sample_count: gfx.gfx.samples, color_attachment: &gfx.gfx.fbos.color_msaa, resolve_target: Some(gfx.view), - }, + } + } else { + yakui_wgpu::SurfaceInfo { + format: self.format, + sample_count: 1, + color_attachment: gfx.view, + resolve_target: None, + } + }; + + self.renderer.paint_with_encoder( + &mut self.yakui, + &gfx.gfx.device, + &gfx.gfx.queue, + gfx.encoder, + surface_info, ); } diff --git a/native_app/src/newgui/hud/windows/settings.rs b/native_app/src/newgui/hud/windows/settings.rs index 0ecfb0f0..7fab3241 100644 --- a/native_app/src/newgui/hud/windows/settings.rs +++ b/native_app/src/newgui/hud/windows/settings.rs @@ -226,6 +226,11 @@ pub fn settings(uiw: &UiWorld, _: &Simulation, opened: &mut bool) { on_secondary_container(), "Ambient Occlusion (SSAO)", ); + checkbox_value( + &mut settings.gfx.msaa, + on_secondary_container(), + "MSAA 4x Anti-aliasing", + ); checkbox_value(&mut settings.gfx.vsync, on_secondary_container(), "VSync"); checkbox_value( &mut settings.gfx.parallel_render,