wgpu: Slight opimitsation to blur filter by not needing to calculate full_width per fragment

This commit is contained in:
Nathan Adams 2023-07-09 15:17:17 +02:00
parent 30e7a1eac6
commit 1aa2ac28c2
5 changed files with 17 additions and 15 deletions

View File

@ -5,10 +5,11 @@ struct Filter {
dir_x: f32, dir_x: f32,
dir_y: f32, dir_y: f32,
// Size of the blur kernel // Full size of the blur kernel (from left to right, ie)
size: f32, full_size: f32,
_padding: f32, // Half size of the blur kernel (from center to right, ie) - without center piece
half_size: f32,
} }
@group(0) @binding(0) var texture: texture_2d<f32>; @group(0) @binding(0) var texture: texture_2d<f32>;
@ -25,11 +26,10 @@ fn main_fragment(in: filter::VertexOutput) -> @location(0) vec4<f32> {
let direction = vec2<f32>(filter_args.dir_x, filter_args.dir_y); let direction = vec2<f32>(filter_args.dir_x, filter_args.dir_y);
var color = vec4<f32>(); var color = vec4<f32>();
let num_samples = 2.0 * filter_args.size + 1.0; let weight = 1.0 / filter_args.full_size;
let weight = 1.0 / num_samples;
for (var i = 0.0; i < num_samples; i += 1.0) { for (var i = 0.0; i < filter_args.full_size; i += 1.0) {
color += textureSample(texture, texture_sampler, in.uv + direction * (i - filter_args.size)) * weight; color += textureSample(texture, texture_sampler, in.uv + direction * (i - filter_args.half_size)) * weight;
} }
return color; return color;

View File

@ -21,8 +21,8 @@ const PASS_SCALES: [f32; 15] = [
#[derive(Copy, Clone, Debug, Pod, Zeroable, PartialEq)] #[derive(Copy, Clone, Debug, Pod, Zeroable, PartialEq)]
struct BlurUniform { struct BlurUniform {
direction: [f32; 2], direction: [f32; 2],
size: f32, full_size: f32,
_padding: f32, half_size: f32,
} }
pub struct BlurFilter { pub struct BlurFilter {
@ -190,12 +190,14 @@ impl BlurFilter {
} else { } else {
filter.blur_y.to_f32() filter.blur_y.to_f32()
}; };
// blur_x/y is the total kernel width; change it to just half excluding center // Full width of the kernel (left edge to right edge)
let strength = ((strength.min(255.0) * pass_scale - 1.0) / 2.0).floor(); let full_size = (strength.min(255.0) * pass_scale).round();
if strength <= 0.0 { if full_size <= 1.0 {
// A strength of 0 is a noop // A width of 1 or less is a noop (it'd just sample itself and nothing else)
continue; continue;
} }
// Radius of the kernel (edge of the center, to right edge), excludes center pixel
let half_size = (full_size - 1.0) / 2.0;
let (previous_view, previous_vertices, previous_width, previous_height) = if first { let (previous_view, previous_vertices, previous_width, previous_height) = if first {
first = false; first = false;
@ -224,8 +226,8 @@ impl BlurFilter {
} else { } else {
[0.0, 1.0 / previous_height] [0.0, 1.0 / previous_height]
}, },
size: strength, full_size,
_padding: 0.0, half_size,
}]), }]),
usage: wgpu::BufferUsages::UNIFORM, usage: wgpu::BufferUsages::UNIFORM,
}); });

Binary file not shown.

Before

Width:  |  Height:  |  Size: 105 KiB

After

Width:  |  Height:  |  Size: 113 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 116 KiB

After

Width:  |  Height:  |  Size: 116 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 66 KiB

After

Width:  |  Height:  |  Size: 66 KiB