use ViewNodeRunner in the post_processing example (#9127)
# Objective - I forgot to update the example after the `ViewNodeRunner` was merged. It was even partially mentioned in one of the comments. ## Solution - Use the `ViewNodeRunner` in the post_processing example - I also broke up a few lines that were a bit long --------- Co-authored-by: JMS55 <47158642+JMS55@users.noreply.github.com>
This commit is contained in:
		
							parent
							
								
									7ccb203b37
								
							
						
					
					
						commit
						171ff1b1e1
					
				| @ -16,7 +16,7 @@ use bevy::{ | ||||
|         extract_component::{ | ||||
|             ComponentUniforms, ExtractComponent, ExtractComponentPlugin, UniformComponentPlugin, | ||||
|         }, | ||||
|         render_graph::{Node, NodeRunError, RenderGraphApp, RenderGraphContext}, | ||||
|         render_graph::{NodeRunError, RenderGraphApp, RenderGraphContext}, | ||||
|         render_resource::{ | ||||
|             BindGroupDescriptor, BindGroupEntry, BindGroupLayout, BindGroupLayoutDescriptor, | ||||
|             BindGroupLayoutEntry, BindingResource, BindingType, CachedRenderPipelineId, | ||||
| @ -27,11 +27,15 @@ use bevy::{ | ||||
|         }, | ||||
|         renderer::{RenderContext, RenderDevice}, | ||||
|         texture::BevyDefault, | ||||
|         view::{ExtractedView, ViewTarget}, | ||||
|         view::ViewTarget, | ||||
|         RenderApp, | ||||
|     }, | ||||
|     utils::Duration, | ||||
| }; | ||||
| use bevy_internal::{ | ||||
|     ecs::query::QueryItem, | ||||
|     render::render_graph::{ViewNode, ViewNodeRunner}, | ||||
| }; | ||||
| 
 | ||||
| fn main() { | ||||
|     App::new() | ||||
| @ -83,7 +87,10 @@ impl Plugin for PostProcessPlugin { | ||||
|             // you need to extract it manually or with the plugin like above.
 | ||||
|             // Add a [`Node`] to the [`RenderGraph`]
 | ||||
|             // The Node needs to impl FromWorld
 | ||||
|             .add_render_graph_node::<PostProcessNode>( | ||||
|             //
 | ||||
|             // The [`ViewNodeRunner`] is a special [`Node`] that will automatically run the node for each view
 | ||||
|             // matching the [`ViewQuery`]
 | ||||
|             .add_render_graph_node::<ViewNodeRunner<PostProcessNode>>( | ||||
|                 // Specify the name of the graph, in this case we want the graph for 3d
 | ||||
|                 core_3d::graph::NAME, | ||||
|                 // It also needs the name of the node
 | ||||
| @ -113,60 +120,42 @@ impl Plugin for PostProcessPlugin { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| /// The post process node used for the render graph
 | ||||
| struct PostProcessNode { | ||||
|     // The node needs a query to gather data from the ECS in order to do its rendering,
 | ||||
|     // but it's not a normal system so we need to define it manually.
 | ||||
|     query: QueryState<&'static ViewTarget, With<ExtractedView>>, | ||||
| } | ||||
| 
 | ||||
| // The post process node used for the render graph
 | ||||
| #[derive(Default)] | ||||
| struct PostProcessNode; | ||||
| impl PostProcessNode { | ||||
|     pub const NAME: &str = "post_process"; | ||||
| } | ||||
| 
 | ||||
| impl FromWorld for PostProcessNode { | ||||
|     fn from_world(world: &mut World) -> Self { | ||||
|         Self { | ||||
|             query: QueryState::new(world), | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl Node for PostProcessNode { | ||||
|     // This will run every frame before the run() method
 | ||||
|     // The important difference is that `self` is `mut` here
 | ||||
|     fn update(&mut self, world: &mut World) { | ||||
|         // Since this is not a system we need to update the query manually.
 | ||||
|         // This is mostly boilerplate. There are plans to remove this in the future.
 | ||||
|         // For now, you can just copy it.
 | ||||
|         self.query.update_archetypes(world); | ||||
|     } | ||||
| // The ViewNode trait is required by the ViewNodeRunner
 | ||||
| impl ViewNode for PostProcessNode { | ||||
|     // The node needs a query to gather data from the ECS in order to do its rendering,
 | ||||
|     // but it's not a normal system so we need to define it manually.
 | ||||
|     //
 | ||||
|     // This query will only run on the view entity
 | ||||
|     type ViewQuery = &'static ViewTarget; | ||||
| 
 | ||||
|     // Runs the node logic
 | ||||
|     // This is where you encode draw commands.
 | ||||
|     //
 | ||||
|     // This will run on every view on which the graph is running. If you don't want your effect to run on every camera,
 | ||||
|     // you'll need to make sure you have a marker component to identify which camera(s) should run the effect.
 | ||||
|     // This will run on every view on which the graph is running.
 | ||||
|     // If you don't want your effect to run on every camera,
 | ||||
|     // you'll need to make sure you have a marker component as part of [`ViewQuery`]
 | ||||
|     // to identify which camera(s) should run the effect.
 | ||||
|     fn run( | ||||
|         &self, | ||||
|         graph_context: &mut RenderGraphContext, | ||||
|         _graph: &mut RenderGraphContext, | ||||
|         render_context: &mut RenderContext, | ||||
|         view_target: QueryItem<Self::ViewQuery>, | ||||
|         world: &World, | ||||
|     ) -> Result<(), NodeRunError> { | ||||
|         // Get the entity of the view for the render graph where this node is running
 | ||||
|         let view_entity = graph_context.view_entity(); | ||||
| 
 | ||||
|         // We get the data we need from the world based on the view entity passed to the node.
 | ||||
|         // The data is the query that was defined earlier in the [`PostProcessNode`]
 | ||||
|         let Ok(view_target) = self.query.get_manual(world, view_entity) else { | ||||
|             return Ok(()); | ||||
|         }; | ||||
| 
 | ||||
|         // Get the pipeline resource that contains the global data we need to create the render pipeline
 | ||||
|         // Get the pipeline resource that contains the global data we need
 | ||||
|         // to create the render pipeline
 | ||||
|         let post_process_pipeline = world.resource::<PostProcessPipeline>(); | ||||
| 
 | ||||
|         // The pipeline cache is a cache of all previously created pipelines.
 | ||||
|         // It is required to avoid creating a new pipeline each frame, which is expensive due to shader compilation.
 | ||||
|         // It is required to avoid creating a new pipeline each frame,
 | ||||
|         // which is expensive due to shader compilation.
 | ||||
|         let pipeline_cache = world.resource::<PipelineCache>(); | ||||
| 
 | ||||
|         // Get the pipeline from the cache
 | ||||
| @ -191,9 +180,11 @@ impl Node for PostProcessNode { | ||||
| 
 | ||||
|         // The bind_group gets created each frame.
 | ||||
|         //
 | ||||
|         // Normally, you would create a bind_group in the Queue set, but this doesn't work with the post_process_write().
 | ||||
|         // Normally, you would create a bind_group in the Queue set,
 | ||||
|         // but this doesn't work with the post_process_write().
 | ||||
|         // The reason it doesn't work is because each post_process_write will alternate the source/destination.
 | ||||
|         // The only way to have the correct source/destination for the bind_group is to make sure you get it during the node execution.
 | ||||
|         // The only way to have the correct source/destination for the bind_group
 | ||||
|         // is to make sure you get it during the node execution.
 | ||||
|         let bind_group = render_context | ||||
|             .render_device() | ||||
|             .create_bind_group(&BindGroupDescriptor { | ||||
| @ -407,7 +398,8 @@ fn update_settings(mut settings: Query<&mut PostProcessSettings>, time: Res<Time | ||||
|         // Scale it to a more reasonable level
 | ||||
|         intensity *= 0.015; | ||||
| 
 | ||||
|         // Set the intensity. This will then be extracted to the render world and uploaded to the gpu automatically.
 | ||||
|         // Set the intensity.
 | ||||
|         // This will then be extracted to the render world and uploaded to the gpu automatically by the [`UniformComponentPlugin`]
 | ||||
|         setting.intensity = intensity; | ||||
|     } | ||||
| } | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 IceSentry
						IceSentry