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::*, | ||||
|     render::{ | ||||
|         extract_component::{ | ||||
|             ComponentUniforms, ExtractComponent, ExtractComponentPlugin, UniformComponentPlugin, | ||||
|             ComponentUniforms, DynamicUniformIndex, ExtractComponent, ExtractComponentPlugin, | ||||
|             UniformComponentPlugin, | ||||
|         }, | ||||
|         render_graph::{ | ||||
|             NodeRunError, RenderGraphApp, RenderGraphContext, RenderLabel, ViewNode, ViewNodeRunner, | ||||
| @ -127,6 +128,9 @@ impl ViewNode for PostProcessNode { | ||||
|         &'static ViewTarget, | ||||
|         // This makes sure the node only runs on cameras with the PostProcessSettings component
 | ||||
|         &'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
 | ||||
| @ -140,7 +144,7 @@ impl ViewNode for PostProcessNode { | ||||
|         &self, | ||||
|         _graph: &mut RenderGraphContext, | ||||
|         render_context: &mut RenderContext, | ||||
|         (view_target, _post_process_settings): QueryItem<Self::ViewQuery>, | ||||
|         (view_target, _post_process_settings, settings_index): QueryItem<Self::ViewQuery>, | ||||
|         world: &World, | ||||
|     ) -> Result<(), NodeRunError> { | ||||
|         // 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,
 | ||||
|         // using the pipeline/bind_group created above
 | ||||
|         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); | ||||
| 
 | ||||
|         Ok(()) | ||||
| @ -243,7 +250,7 @@ impl FromWorld for PostProcessPipeline { | ||||
|                     // The sampler that will be used to sample the screen texture
 | ||||
|                     sampler(SamplerBindingType::Filtering), | ||||
|                     // 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