From e662690922842d8aa6ce4c8b33e7c2f5ff4c5209 Mon Sep 17 00:00:00 2001 From: Paris DOUADY Date: Tue, 23 Jan 2024 19:34:48 +0100 Subject: [PATCH] improve blur algorithm --- assets/shaders/ui_blur.wgsl | 26 ++++++++++++++++++---- engine/src/passes/blur.rs | 44 ++++++++++++++++++++++++++----------- 2 files changed, 53 insertions(+), 17 deletions(-) diff --git a/assets/shaders/ui_blur.wgsl b/assets/shaders/ui_blur.wgsl index 91273229..f25b533e 100644 --- a/assets/shaders/ui_blur.wgsl +++ b/assets/shaders/ui_blur.wgsl @@ -27,12 +27,30 @@ struct FragmentOutput { @fragment fn downscale(@location(0) v_TexCoord: vec2) -> FragmentOutput { - let o_Target = textureSampleLevel(t_Color, s_Color, v_TexCoord, 0.0); - return FragmentOutput(o_Target); + let dim: vec2 = textureDimensions(t_Color, 0); + let halfpixel = vec2(0.5 / f32(dim.x), 0.5 / f32(dim.y)); + let halfpixel_rot = vec2(halfpixel.x, -halfpixel.y); + + var sum: vec3 = textureSampleLevel(t_Color, s_Color, v_TexCoord, 0.0).rgb * 4.0; + sum += textureSampleLevel(t_Color, s_Color, v_TexCoord + halfpixel, 0.0).rgb; + sum += textureSampleLevel(t_Color, s_Color, v_TexCoord - halfpixel, 0.0).rgb; + sum += textureSampleLevel(t_Color, s_Color, v_TexCoord + halfpixel_rot, 0.0).rgb; + sum += textureSampleLevel(t_Color, s_Color, v_TexCoord - halfpixel_rot, 0.0).rgb; + return FragmentOutput(vec4(sum / 8.0, 1.0)); } @fragment fn upscale(@location(0) v_TexCoord: vec2) -> FragmentOutput { - let o_Target = textureSampleLevel(t_Color, s_Color, v_TexCoord, 0.0); - return FragmentOutput(o_Target); + let dim: vec2 = textureDimensions(t_Color, 0); + let halfpixel = vec2(0.5 / f32(dim.x), 0.5 / f32(dim.y)); + + var sum: vec3 = textureSampleLevel(t_Color, s_Color, v_TexCoord + vec2(-halfpixel.x * 2.0, 0.0), 0.0).rgb; + sum += textureSampleLevel(t_Color, s_Color, v_TexCoord + vec2(-halfpixel.x, halfpixel.y), 0.0).rgb * 2.0; + sum += textureSampleLevel(t_Color, s_Color, v_TexCoord + vec2(0.0, halfpixel.y * 2.0), 0.0).rgb; + sum += textureSampleLevel(t_Color, s_Color, v_TexCoord + vec2(halfpixel.x, halfpixel.y), 0.0).rgb * 2.0; + sum += textureSampleLevel(t_Color, s_Color, v_TexCoord + vec2(halfpixel.x * 2.0, 0.0), 0.0).rgb; + sum += textureSampleLevel(t_Color, s_Color, v_TexCoord + vec2(halfpixel.x, -halfpixel.y), 0.0).rgb * 2.0; + sum += textureSampleLevel(t_Color, s_Color, v_TexCoord + vec2(0.0, -halfpixel.y * 2.0), 0.0).rgb; + sum += textureSampleLevel(t_Color, s_Color, v_TexCoord + vec2(-halfpixel.x, -halfpixel.y), 0.0).rgb * 2.0; + return FragmentOutput(vec4(sum / 12.0, 1.0)); } diff --git a/engine/src/passes/blur.rs b/engine/src/passes/blur.rs index 8e2c7492..81c47bba 100644 --- a/engine/src/passes/blur.rs +++ b/engine/src/passes/blur.rs @@ -19,20 +19,36 @@ const DOWNSCALE_PASSES: u32 = 2; pub fn gen_ui_blur(gfx: &GfxContext, encs: &mut Encoders, frame: &TextureView) { profiling::scope!("ui blur pass"); + let tex = &gfx.fbos.ui_blur; + initial_downscale(gfx, encs, frame); + //do_pass( + // gfx, + // encs, + // UIBlurPipeline::Downscale, + // frame, + // &tex.mip_view(0), + //); + for mip_level in 0..DOWNSCALE_PASSES { do_pass( gfx, encs, UIBlurPipeline::Downscale, - mip_level, - mip_level + 1, + &tex.mip_view(mip_level), + &tex.mip_view(mip_level + 1), ); } for mip_level in (0..DOWNSCALE_PASSES).rev() { - do_pass(gfx, encs, UIBlurPipeline::Upscale, mip_level + 1, mip_level); + do_pass( + gfx, + encs, + UIBlurPipeline::Upscale, + &tex.mip_view(mip_level + 1), + &tex.mip_view(mip_level), + ); } } @@ -50,11 +66,13 @@ fn initial_downscale(gfx: &GfxContext, encs: &mut Encoders, frame: &TextureView) ); } -fn do_pass(gfx: &GfxContext, encs: &mut Encoders, pipeline: UIBlurPipeline, src: u32, dst: u32) { - let tex = &gfx.fbos.ui_blur; - let src_view = tex.mip_view(src); - let dst_view = tex.mip_view(dst); - +fn do_pass( + gfx: &GfxContext, + encs: &mut Encoders, + pipeline: UIBlurPipeline, + src_view: &TextureView, + dst_view: &TextureView, +) { let pipe = gfx.get_pipeline(pipeline); let bg = gfx.device.create_bind_group(&wgpu::BindGroupDescriptor { @@ -63,7 +81,7 @@ fn do_pass(gfx: &GfxContext, encs: &mut Encoders, pipeline: UIBlurPipeline, src: entries: &[ wgpu::BindGroupEntry { binding: 0, - resource: wgpu::BindingResource::TextureView(&src_view), + resource: wgpu::BindingResource::TextureView(src_view), }, wgpu::BindGroupEntry { binding: 1, @@ -73,12 +91,12 @@ fn do_pass(gfx: &GfxContext, encs: &mut Encoders, pipeline: UIBlurPipeline, src: }); let mut blur_pass = encs.end.begin_render_pass(&RenderPassDescriptor { - label: Some(&*format!("ui blur pass {:?} {} -> {}", pipeline, src, dst)), + label: Some(&*format!("ui blur pass {:?}", pipeline)), color_attachments: &[Some(RenderPassColorAttachment { - view: &dst_view, + view: dst_view, resolve_target: None, ops: wgpu::Operations { - load: wgpu::LoadOp::Load, + load: wgpu::LoadOp::Clear(wgpu::Color::TRANSPARENT), store: wgpu::StoreOp::Store, }, })], @@ -87,7 +105,7 @@ fn do_pass(gfx: &GfxContext, encs: &mut Encoders, pipeline: UIBlurPipeline, src: occlusion_query_set: None, }); - blur_pass.set_pipeline(gfx.get_pipeline(UIBlurPipeline::Downscale)); + blur_pass.set_pipeline(pipe); blur_pass.set_bind_group(0, &bg, &[]); blur_pass.draw(0..3, 0..1); }