Skip to content

Commit

Permalink
fix bloom viewport (bevyengine#6802)
Browse files Browse the repository at this point in the history
# Objective

fix bloom when used on a camera with a viewport specified

## Solution

- pass viewport into the prefilter shader, and use it to read from the correct section of the original rendered screen
- don't apply viewport for the intermediate bloom passes, only for the final blend output
  • Loading branch information
robtfm authored and ItsDoot committed Feb 1, 2023
1 parent d7be49b commit 56cfc6d
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 16 deletions.
6 changes: 4 additions & 2 deletions crates/bevy_core_pipeline/src/bloom/bloom.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ struct BloomUniforms {
knee: f32,
scale: f32,
intensity: f32,
viewport: vec4<f32>,
};

@group(0) @binding(0)
Expand Down Expand Up @@ -87,7 +88,8 @@ fn sample_original_3x3_tent(uv: vec2<f32>, scale: vec2<f32>) -> vec4<f32> {
}

@fragment
fn downsample_prefilter(@location(0) uv: vec2<f32>) -> @location(0) vec4<f32> {
fn downsample_prefilter(@location(0) output_uv: vec2<f32>) -> @location(0) vec4<f32> {
let sample_uv = uniforms.viewport.xy + output_uv * uniforms.viewport.zw;
let texel_size = 1.0 / vec2<f32>(textureDimensions(original));

let scale = texel_size;
Expand All @@ -98,7 +100,7 @@ fn downsample_prefilter(@location(0) uv: vec2<f32>) -> @location(0) vec4<f32> {
0.25 / uniforms.knee,
);

var o: vec4<f32> = sample_13_tap(uv, scale);
var o: vec4<f32> = sample_13_tap(sample_uv, scale);

o = quadratic_threshold(o, uniforms.threshold, curve);
o = max(o, vec4<f32>(0.00001));
Expand Down
29 changes: 15 additions & 14 deletions crates/bevy_core_pipeline/src/bloom/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use bevy_ecs::{
system::{Commands, Query, Res, ResMut, Resource},
world::{FromWorld, World},
};
use bevy_math::UVec2;
use bevy_math::{UVec2, UVec4, Vec4};
use bevy_reflect::{Reflect, TypeUuid};
use bevy_render::{
camera::ExtractedCamera,
Expand Down Expand Up @@ -152,18 +152,27 @@ impl ExtractComponent for BloomSettings {
return None;
}

camera.physical_viewport_size().map(|size| {
if let (Some((origin, _)), Some(size), Some(target_size)) = (
camera.physical_viewport_rect(),
camera.physical_viewport_size(),
camera.physical_target_size(),
) {
let min_view = size.x.min(size.y) / 2;
let mip_count = calculate_mip_count(min_view);
let scale = (min_view / 2u32.pow(mip_count)) as f32 / 8.0;

BloomUniform {
Some(BloomUniform {
threshold: settings.threshold,
knee: settings.knee,
scale: settings.scale * scale,
intensity: settings.intensity,
}
})
viewport: UVec4::new(origin.x, origin.y, size.x, size.y).as_vec4()
/ UVec4::new(target_size.x, target_size.y, target_size.x, target_size.y)
.as_vec4(),
})
} else {
None
}
}
}

Expand Down Expand Up @@ -246,9 +255,6 @@ impl Node for BloomNode {
&bind_groups.prefilter_bind_group,
&[uniform_index.index()],
);
if let Some(viewport) = camera.viewport.as_ref() {
prefilter_pass.set_camera_viewport(viewport);
}
prefilter_pass.draw(0..3, 0..1);
}

Expand All @@ -270,9 +276,6 @@ impl Node for BloomNode {
&bind_groups.downsampling_bind_groups[mip as usize - 1],
&[uniform_index.index()],
);
if let Some(viewport) = camera.viewport.as_ref() {
downsampling_pass.set_camera_viewport(viewport);
}
downsampling_pass.draw(0..3, 0..1);
}

Expand All @@ -294,9 +297,6 @@ impl Node for BloomNode {
&bind_groups.upsampling_bind_groups[mip as usize - 1],
&[uniform_index.index()],
);
if let Some(viewport) = camera.viewport.as_ref() {
upsampling_pass.set_camera_viewport(viewport);
}
upsampling_pass.draw(0..3, 0..1);
}

Expand Down Expand Up @@ -612,6 +612,7 @@ pub struct BloomUniform {
knee: f32,
scale: f32,
intensity: f32,
viewport: Vec4,
}

#[derive(Component)]
Expand Down

0 comments on commit 56cfc6d

Please sign in to comment.