Expose max_mip_dimension and uv_offset in BloomSettings. (#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 <alice.i.cecile@gmail.com>
This commit is contained in:
		
							parent
							
								
									6183b56b5d
								
							
						
					
					
						commit
						882973a528
					
				| @ -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>; | ||||
| @ -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; | ||||
|  | ||||
| @ -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 { | ||||
|  | ||||
| @ -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 { | ||||
| @ -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. | ||||
|             }; | ||||
|  | ||||
| @ -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.
 | ||||
| @ -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.
 | ||||
| @ -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.
 | ||||
| @ -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, | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| @ -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)) | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Josiah Putman
						Josiah Putman