bevyengine / bevyengine/bevy

Need a simpler way to add custom prepasses (light camera & main camera)

Open
#21,127 0 comments 1 reaction 0 assignees View on GitHub
A-Rendering C-Feature S-Needs-Design X-Contentious
Dominant language
Rust
Stars
48.2k
Forks
4.8k
Avg merge
3d 22h
Merged PRs (30d)
161

Description

## What problem does this solve or what need does it fill?

When working on NPR rendering, various types of prepasses are often required. In my project, some objects need additional custom directional shadow passes and custom main camera prepasses.

* For **custom shadow passes**, I currently copy most of the code from `bevy_pbr/render/light.rs`. It works, but it’s hard to maintain. There are many low level details, lots of guard clauses, and it feels fragile, an update could silently break things with subtle bugs.
* For **custom main camera prepasses**, the `Material` trait’s `prepass_xxx_shader` methods work for small tweaks (like vertex animation). But adding entirely new prepasses isn’t possible because of the fixed `FragmentOutput` bindings. The only option is to rebuild a full `SpecializedMeshPipeline`, which runs into the same maintenance issues as above.

## What solution would you like?

Not sure, but here are some thoughts:

1. I'm not sure if this is feasible, but perhaps users could create their own shadow pass nodes and reuse as many outputs as possible from existing systems. They could modify based on that, avoiding the need to recreate complex `prepare`, `specialize`, and `queue` systems again.
This might require cloning and editing structures like `BinnedRenderPhase`. The current API makes doing this manually both complex and unsafe. When encountering private fields, it becomes impossible. Maybe we need something like a `specialize` API to facilitate this.

2. Perhaps we could create a new abstraction layer for adding custom prepasses, similar to #20414, that offers enough flexibility while hiding the complex details.

3. Alternatively, going back to a camera-driven rendering approach: allowing multiple materials per entity and having materials respect `RenderLayer`. Users could render objects with a `CustomPrepassMaterial` via a `PrepassCamera` onto a texture, then use it in post processing.
Related to #20092, #12208, #19008.

## What alternative(s) have you considered?

The current workaround is to add N cameras, duplicate N copies of entities, and configure RenderLayer. This works but it increases memory usage and makes it very inconvenient to keep mesh entities and camera entities in sync.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.