Custom Post-Processing Example is too low-level and doesn't generalize to reading depth buffer / getting view position
- Dominant language
- Rust
- Stars
- 48.2k
- Forks
- 4.8k
- Avg merge
- 3d 16h
- Merged PRs (30d)
- 171
Description
The [custom post-processing example](https://bevy.org/examples/shaders/custom-post-processing/) shows how to read from and write to the camera target texture, but that's it.
A lot of effects require reading other information, like normals, depth, and camera view transform. Unfortunately, these don't fit into the pattern outlined by this example.
For example, [bevy atmosphere](https://github.com/bevyengine/bevy/blob/8878083cf77fc36a34aa03328fc8e561e4b9894f/crates/bevy_pbr/src/atmosphere/resources.rs#L568) introduces the `prepare_atmosphere_bind_groups` system, added to the `RenderApp` `RenderSystems::PrepareBindGroups` system set. As far as I can tell, this is necessary to be able to get layout information for uniforms like the view.
But there's no corresponding system in the custom-post-processing example, so even copying the logic from `bevy_atmosphere` is difficult. Since the custom-post-processing example is trying to be simple, it ends up completely skipping a pattern that becomes (I think?) necessary if you want to write a more complex post-process pass.
---
Error messages while debugging post-processing are also not ideal. Here are two that I ran into, for example:
```
thread '' panicked at C:\Users\nfenn\.cargo\registry\src\index.crates.io-1949cf8c6b5b557f\wgpu-24.0.5\src\backend\wgpu_core.rs:3273:26:
wgpu error: Validation Error
Caused by:
In RenderPass::end
In a set_bind_group command
BindGroup with 'post_process_bind_group' label 0 expects 2 dynamic offsets. However 1 dynamic offset were provided.
```
In the above case, I added the `view` uniform to the bind group, but forgot to update the `set_bind_group` call to include the additional `dynamic_uniform_indices` value. In theory, Bevy has enough info (in principle) to reconstruct the exact mistake that I made, and tell me which bind group members need dynamic offsets (e.g. their names, ideally).
```
thread '' panicked at C:\Users\nfenn\.cargo\registry\src\index.crates.io-1949cf8c6b5b557f\wgpu-24.0.5\src\backend\wgpu_core.rs:3273:26:
wgpu error: Validation Error
Caused by:
In RenderPass::end
In a pass parameter
Attempted to use Texture with 'main_texture_a' label (mips 0..1 layers 0..1) with conflicting usages. Current usage TextureUses(RESOURCE) and new usage TextureUses(COLOR_TARGET). TextureUses(COLOR_TARGET) is an exclusive usage and cannot be used with any other usages within the usage scope (renderpass or compute dispatch).
```
I am still not quite sure what's going on with this error. I must have accidentally declared that I'm both reading and writing to the render target, but I don't know how.
If you compare this to writing an `ExtendedMaterial`, there's a much, much steeper learning curve for post-processing, and very few real-world examples to go off of which are simple enough to adapt for custom shaders.
---
Ideally, the interface to implement for this kind of custom shader would be something like (pseudocode):
```rs
#[derive(Component)]
struct PostProcessingSettings {
radius: f32,
}
#[derive(CustomPostProcessingPass);
struct MyPostProcessing {
#[binding(0)]
depth: DepthTexture,
#[binding(1)]
view: ViewTexture,
#[binding(2)]
#[camera_component]
settings: PostProcessingSettings,
#[binding(3)]
#[view]
view: View,
}
impl PostProcessingShader for MyPostProcessing {
fn shader_path() -> &str {
"my_shader.wgsl"
}
}
```
For most bindings, there is an "obvious" place to obtain the binding - a type-directed API which knows how to look up various components/resources/etc to properly build/specialize the post-processing pass seems like it could be built declaratively, instead of requiring e.g. duplicate effort to define a `BindGroupLayout` and then separately extract/build a `BindGroup` etc.
Contributor guide
Research direction
Start with the custom post-processing example and the prepare_atmosphere_bind_groups system in crates/bevy_pbr/src/atmosphere/resources.rs, including its RenderApp and RenderSystems::PrepareBindGroups integration. Compare the example with the reported bind-group and texture-usage errors; completion should leave a documented, generalizable path for complex post-processing bindings and clearer guidance for these failures.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- computer-graphics
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 28/100