Use dynamic uniform buffer in post processing example (#13540)
# Objective While learning about shaders and pipelines, I found this example to be misleading; it wasn't clear to me how the node knew what the correct "instance" of `PostProcessSettings` we should send to the shader (as the combination of `ExtractComponentPlugin` and `UniformComponentPlugin` extracts + sends _all_ of our `PostProcessSetting` components to the GPU). The goal of this PR is to clarify how to target the view specific `PostProcessSettings` in the shader when there are multiple cameras. ## Solution To accomplish this, we can use a dynamic uniform buffer for `PostProcessSettings`, querying for the relevant `DynamicUniformIndex` in the `PostProcessNode` to get the relevant index to use with the bind group. While the example in its current state is _correct_, I believe that fact that it's intended to showcase a per camera post processing effect warrants a dynamic uniform buffer (even though in the context of this example we have only one camera, and therefore no adverse behaviour). ## Testing - Run the `post_processing` example before and after this change, verifying they behave the same. ## Reviewer notes This is my first PR to Bevy, and I'm by no means an expert in the world of rendering (though I'm trying to learn all I can). If there's a better way to do this / a reason not to take this route, I'd love to hear it! Thanks in advance.
This commit is contained in:
		
							parent
							
								
									ba198151a4
								
							
						
					
					
						commit
						061baa4ff7
					
				| @ -15,7 +15,8 @@ use bevy::{ | |||||||
|     prelude::*, |     prelude::*, | ||||||
|     render::{ |     render::{ | ||||||
|         extract_component::{ |         extract_component::{ | ||||||
|             ComponentUniforms, ExtractComponent, ExtractComponentPlugin, UniformComponentPlugin, |             ComponentUniforms, DynamicUniformIndex, ExtractComponent, ExtractComponentPlugin, | ||||||
|  |             UniformComponentPlugin, | ||||||
|         }, |         }, | ||||||
|         render_graph::{ |         render_graph::{ | ||||||
|             NodeRunError, RenderGraphApp, RenderGraphContext, RenderLabel, ViewNode, ViewNodeRunner, |             NodeRunError, RenderGraphApp, RenderGraphContext, RenderLabel, ViewNode, ViewNodeRunner, | ||||||
| @ -127,6 +128,9 @@ impl ViewNode for PostProcessNode { | |||||||
|         &'static ViewTarget, |         &'static ViewTarget, | ||||||
|         // This makes sure the node only runs on cameras with the PostProcessSettings component
 |         // This makes sure the node only runs on cameras with the PostProcessSettings component
 | ||||||
|         &'static PostProcessSettings, |         &'static PostProcessSettings, | ||||||
|  |         // As there could be multiple post processing components sent to the GPU (one per camera),
 | ||||||
|  |         // we need to get the index of the one that is associated with the current view.
 | ||||||
|  |         &'static DynamicUniformIndex<PostProcessSettings>, | ||||||
|     ); |     ); | ||||||
| 
 | 
 | ||||||
|     // Runs the node logic
 |     // Runs the node logic
 | ||||||
| @ -140,7 +144,7 @@ impl ViewNode for PostProcessNode { | |||||||
|         &self, |         &self, | ||||||
|         _graph: &mut RenderGraphContext, |         _graph: &mut RenderGraphContext, | ||||||
|         render_context: &mut RenderContext, |         render_context: &mut RenderContext, | ||||||
|         (view_target, _post_process_settings): QueryItem<Self::ViewQuery>, |         (view_target, _post_process_settings, settings_index): QueryItem<Self::ViewQuery>, | ||||||
|         world: &World, |         world: &World, | ||||||
|     ) -> Result<(), NodeRunError> { |     ) -> Result<(), NodeRunError> { | ||||||
|         // Get the pipeline resource that contains the global data we need
 |         // Get the pipeline resource that contains the global data we need
 | ||||||
| @ -212,7 +216,10 @@ impl ViewNode for PostProcessNode { | |||||||
|         // This is mostly just wgpu boilerplate for drawing a fullscreen triangle,
 |         // This is mostly just wgpu boilerplate for drawing a fullscreen triangle,
 | ||||||
|         // using the pipeline/bind_group created above
 |         // using the pipeline/bind_group created above
 | ||||||
|         render_pass.set_render_pipeline(pipeline); |         render_pass.set_render_pipeline(pipeline); | ||||||
|         render_pass.set_bind_group(0, &bind_group, &[]); |         // By passing in the index of the post process settings on this view, we ensure
 | ||||||
|  |         // that in the event that multiple settings were sent to the GPU (as would be the
 | ||||||
|  |         // case with multiple cameras), we use the correct one.
 | ||||||
|  |         render_pass.set_bind_group(0, &bind_group, &[settings_index.index()]); | ||||||
|         render_pass.draw(0..3, 0..1); |         render_pass.draw(0..3, 0..1); | ||||||
| 
 | 
 | ||||||
|         Ok(()) |         Ok(()) | ||||||
| @ -243,7 +250,7 @@ impl FromWorld for PostProcessPipeline { | |||||||
|                     // The sampler that will be used to sample the screen texture
 |                     // The sampler that will be used to sample the screen texture
 | ||||||
|                     sampler(SamplerBindingType::Filtering), |                     sampler(SamplerBindingType::Filtering), | ||||||
|                     // The settings uniform that will control the effect
 |                     // The settings uniform that will control the effect
 | ||||||
|                     uniform_buffer::<PostProcessSettings>(false), |                     uniform_buffer::<PostProcessSettings>(true), | ||||||
|                 ), |                 ), | ||||||
|             ), |             ), | ||||||
|         ); |         ); | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 James Gayfer
						James Gayfer