Skip to content

Commit

Permalink
Expose max_mip_dimension and uv_offset in BloomSettings. (bevyengine#…
Browse files Browse the repository at this point in the history
…14512)

# Objective

By default, Bevy's bloom effect shows square artifacts on small bright
particles due to a low max mip resolution. This PR makes this
configurable via BloomSettings so users can customize these parameters
instead of having them in private module constants.

## Solution

Expose max_mip_dimension and uv_offset in BloomSettings.

## Testing

I tested these changes by running the Bloom 2D / 3D examples.

---------

Co-authored-by: Alice Cecile <[email protected]>
  • Loading branch information
Katsutoshii and alice-i-cecile authored Aug 13, 2024
1 parent 6183b56 commit 882973a
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 11 deletions.
7 changes: 4 additions & 3 deletions crates/bevy_core_pipeline/src/bloom/bloom.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ struct BloomUniforms {
threshold_precomputations: vec4<f32>,
viewport: vec4<f32>,
aspect: f32,
uv_offset: f32
};

@group(0) @binding(0) var input_texture: texture_2d<f32>;
Expand Down Expand Up @@ -94,9 +95,9 @@ fn sample_input_13_tap(uv: vec2<f32>) -> vec3<f32> {

// [COD] slide 162
fn sample_input_3x3_tent(uv: vec2<f32>) -> vec3<f32> {
// Radius. Empirically chosen by and tweaked from the LearnOpenGL article.
let x = 0.004 / uniforms.aspect;
let y = 0.004;
// UV offsets configured from uniforms.
let x = uniforms.uv_offset / uniforms.aspect;
let y = uniforms.uv_offset;

let a = textureSample(input_texture, s, vec2<f32>(uv.x - x, uv.y + y)).rgb;
let b = textureSample(input_texture, s, vec2<f32>(uv.x, uv.y + y)).rgb;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ pub struct BloomUniforms {
pub threshold_precomputations: Vec4,
pub viewport: Vec4,
pub aspect: f32,
pub uv_offset: f32,
}

impl FromWorld for BloomDownsamplingPipeline {
Expand Down
12 changes: 4 additions & 8 deletions crates/bevy_core_pipeline/src/bloom/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,6 @@ const BLOOM_SHADER_HANDLE: Handle<Shader> = Handle::weak_from_u128(9295994769239

const BLOOM_TEXTURE_FORMAT: TextureFormat = TextureFormat::Rg11b10Float;

// Maximum size of each dimension for the largest mipchain texture used in downscaling/upscaling.
// 512 behaves well with the UV offset of 0.004 used in bloom.wgsl
const MAX_MIP_DIMENSION: u32 = 512;

pub struct BloomPlugin;

impl Plugin for BloomPlugin {
Expand Down Expand Up @@ -328,18 +324,18 @@ fn prepare_bloom_textures(
mut commands: Commands,
mut texture_cache: ResMut<TextureCache>,
render_device: Res<RenderDevice>,
views: Query<(Entity, &ExtractedCamera), With<BloomSettings>>,
views: Query<(Entity, &ExtractedCamera, &BloomSettings)>,
) {
for (entity, camera) in &views {
for (entity, camera, settings) in &views {
if let Some(UVec2 {
x: width,
y: height,
}) = camera.physical_viewport_size
{
// How many times we can halve the resolution minus one so we don't go unnecessarily low
let mip_count = MAX_MIP_DIMENSION.ilog2().max(2) - 1;
let mip_count = settings.max_mip_dimension.ilog2().max(2) - 1;
let mip_height_ratio = if height != 0 {
MAX_MIP_DIMENSION as f32 / height as f32
settings.max_mip_dimension as f32 / height as f32
} else {
0.
};
Expand Down
18 changes: 18 additions & 0 deletions crates/bevy_core_pipeline/src/bloom/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,20 @@ pub struct BloomSettings {
/// configured in a non-energy-conserving way,
/// otherwise set to [`BloomCompositeMode::EnergyConserving`].
pub composite_mode: BloomCompositeMode,

/// Maximum size of each dimension for the largest mipchain texture used in downscaling/upscaling.
/// Only tweak if you are seeing visual artifacts.
pub max_mip_dimension: u32,

/// UV offset for bloom shader. Ideally close to 2.0 / `max_mip_dimension`.
/// Only tweak if you are seeing visual artifacts.
pub uv_offset: f32,
}

impl BloomSettings {
const DEFAULT_MAX_MIP_DIMENSION: u32 = 512;
const DEFAULT_UV_OFFSET: f32 = 0.004;

/// The default bloom preset.
///
/// This uses the [`EnergyConserving`](BloomCompositeMode::EnergyConserving) composite mode.
Expand All @@ -118,6 +129,8 @@ impl BloomSettings {
threshold_softness: 0.0,
},
composite_mode: BloomCompositeMode::EnergyConserving,
max_mip_dimension: Self::DEFAULT_MAX_MIP_DIMENSION,
uv_offset: Self::DEFAULT_UV_OFFSET,
};

/// A preset that's similar to how older games did bloom.
Expand All @@ -131,6 +144,8 @@ impl BloomSettings {
threshold_softness: 0.2,
},
composite_mode: BloomCompositeMode::Additive,
max_mip_dimension: Self::DEFAULT_MAX_MIP_DIMENSION,
uv_offset: Self::DEFAULT_UV_OFFSET,
};

/// A preset that applies a very strong bloom, and blurs the whole screen.
Expand All @@ -144,6 +159,8 @@ impl BloomSettings {
threshold_softness: 0.0,
},
composite_mode: BloomCompositeMode::EnergyConserving,
max_mip_dimension: Self::DEFAULT_MAX_MIP_DIMENSION,
uv_offset: Self::DEFAULT_UV_OFFSET,
};
}

Expand Down Expand Up @@ -213,6 +230,7 @@ impl ExtractComponent for BloomSettings {
/ UVec4::new(target_size.x, target_size.y, target_size.x, target_size.y)
.as_vec4(),
aspect: AspectRatio::from_pixels(size.x, size.y).into(),
uv_offset: settings.uv_offset,
};

Some((settings.clone(), uniform))
Expand Down

0 comments on commit 882973a

Please sign in to comment.