fix bloom viewport (#6802)
# 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
This commit is contained in:
		
							parent
							
								
									1cc663f290
								
							
						
					
					
						commit
						45dfa71e03
					
				| @ -5,6 +5,7 @@ struct BloomUniforms { | |||||||
|     knee: f32, |     knee: f32, | ||||||
|     scale: f32, |     scale: f32, | ||||||
|     intensity: f32, |     intensity: f32, | ||||||
|  |     viewport: vec4<f32>, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| @group(0) @binding(0) | @group(0) @binding(0) | ||||||
| @ -87,7 +88,8 @@ fn sample_original_3x3_tent(uv: vec2<f32>, scale: vec2<f32>) -> vec4<f32> { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @fragment | @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 texel_size = 1.0 / vec2<f32>(textureDimensions(original)); | ||||||
| 
 | 
 | ||||||
|     let scale = texel_size; |     let scale = texel_size; | ||||||
| @ -98,7 +100,7 @@ fn downsample_prefilter(@location(0) uv: vec2<f32>) -> @location(0) vec4<f32> { | |||||||
|         0.25 / uniforms.knee, |         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 = quadratic_threshold(o, uniforms.threshold, curve); | ||||||
|     o = max(o, vec4<f32>(0.00001)); |     o = max(o, vec4<f32>(0.00001)); | ||||||
|  | |||||||
| @ -7,7 +7,7 @@ use bevy_ecs::{ | |||||||
|     system::{Commands, Query, Res, ResMut, Resource}, |     system::{Commands, Query, Res, ResMut, Resource}, | ||||||
|     world::{FromWorld, World}, |     world::{FromWorld, World}, | ||||||
| }; | }; | ||||||
| use bevy_math::UVec2; | use bevy_math::{UVec2, UVec4, Vec4}; | ||||||
| use bevy_reflect::{Reflect, TypeUuid}; | use bevy_reflect::{Reflect, TypeUuid}; | ||||||
| use bevy_render::{ | use bevy_render::{ | ||||||
|     camera::ExtractedCamera, |     camera::ExtractedCamera, | ||||||
| @ -152,18 +152,27 @@ impl ExtractComponent for BloomSettings { | |||||||
|             return None; |             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 min_view = size.x.min(size.y) / 2; | ||||||
|             let mip_count = calculate_mip_count(min_view); |             let mip_count = calculate_mip_count(min_view); | ||||||
|             let scale = (min_view / 2u32.pow(mip_count)) as f32 / 8.0; |             let scale = (min_view / 2u32.pow(mip_count)) as f32 / 8.0; | ||||||
| 
 | 
 | ||||||
|             BloomUniform { |             Some(BloomUniform { | ||||||
|                 threshold: settings.threshold, |                 threshold: settings.threshold, | ||||||
|                 knee: settings.knee, |                 knee: settings.knee, | ||||||
|                 scale: settings.scale * scale, |                 scale: settings.scale * scale, | ||||||
|                 intensity: settings.intensity, |                 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 | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -246,9 +255,6 @@ impl Node for BloomNode { | |||||||
|                 &bind_groups.prefilter_bind_group, |                 &bind_groups.prefilter_bind_group, | ||||||
|                 &[uniform_index.index()], |                 &[uniform_index.index()], | ||||||
|             ); |             ); | ||||||
|             if let Some(viewport) = camera.viewport.as_ref() { |  | ||||||
|                 prefilter_pass.set_camera_viewport(viewport); |  | ||||||
|             } |  | ||||||
|             prefilter_pass.draw(0..3, 0..1); |             prefilter_pass.draw(0..3, 0..1); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
| @ -270,9 +276,6 @@ impl Node for BloomNode { | |||||||
|                 &bind_groups.downsampling_bind_groups[mip as usize - 1], |                 &bind_groups.downsampling_bind_groups[mip as usize - 1], | ||||||
|                 &[uniform_index.index()], |                 &[uniform_index.index()], | ||||||
|             ); |             ); | ||||||
|             if let Some(viewport) = camera.viewport.as_ref() { |  | ||||||
|                 downsampling_pass.set_camera_viewport(viewport); |  | ||||||
|             } |  | ||||||
|             downsampling_pass.draw(0..3, 0..1); |             downsampling_pass.draw(0..3, 0..1); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
| @ -294,9 +297,6 @@ impl Node for BloomNode { | |||||||
|                 &bind_groups.upsampling_bind_groups[mip as usize - 1], |                 &bind_groups.upsampling_bind_groups[mip as usize - 1], | ||||||
|                 &[uniform_index.index()], |                 &[uniform_index.index()], | ||||||
|             ); |             ); | ||||||
|             if let Some(viewport) = camera.viewport.as_ref() { |  | ||||||
|                 upsampling_pass.set_camera_viewport(viewport); |  | ||||||
|             } |  | ||||||
|             upsampling_pass.draw(0..3, 0..1); |             upsampling_pass.draw(0..3, 0..1); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
| @ -612,6 +612,7 @@ pub struct BloomUniform { | |||||||
|     knee: f32, |     knee: f32, | ||||||
|     scale: f32, |     scale: f32, | ||||||
|     intensity: f32, |     intensity: f32, | ||||||
|  |     viewport: Vec4, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[derive(Component)] | #[derive(Component)] | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 robtfm
						robtfm