Skip to content

Commit

Permalink
Use dynamic uniform buffer in post processing example (#13540)
Browse files Browse the repository at this point in the history
# 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.
  • Loading branch information
jgayfer authored Jun 14, 2024
1 parent ba19815 commit 061baa4
Showing 1 changed file with 11 additions and 4 deletions.
15 changes: 11 additions & 4 deletions examples/shader/post_processing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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(())
Expand Down Expand Up @@ -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),
),
),
);
Expand Down

0 comments on commit 061baa4

Please sign in to comment.