OcclusionCulling crashes without DepthPrepass
- Dominant language
- Rust
- Stars
- 48.2k
- Forks
- 4.8k
- Avg merge
- 3d 16h
- Merged PRs (30d)
- 171
Description
[Documentation](https://docs.rs/bevy/latest/bevy/render/experimental/occlusion_culling/struct.OcclusionCulling.html) says that
> Occlusion culling currently requires a DepthPrepass. If no depth prepass is present on the view, the OcclusionCulling component will be ignored.
However the actual behavior is a crash during the preparation for mipmap generation of the depth texture:
```
ERROR wgpu::backend::wgpu_core: Handling wgpu errors as fatal by default
thread 'Compute Task Pool (12)' (383983) panicked at ~/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/wgpu-28.0.0/src/backend/wgpu_core.rs:1254:26:
wgpu error: Validation Error
Caused by:
In Device::create_bind_group, label = 'downsample multisample depth bind group'
Usage flags TextureUsages(RENDER_ATTACHMENT) of TextureView with '' label do not contain required usage flags TextureUsages(TEXTURE_BINDING)
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Encountered a panic in system `bevy_core_pipeline::mip_generation::experimental::depth::prepare_downsample_depth_view_bind_groups`!
```
The `MipGenerationPlugin` is a dependent plugin of `CorePipelinePlugin`, and system `prepare_downsample_depth_view_bind_groups` constructs the bind groups referencing the source depth textures corresponding to either a camera view or a view used for shadow mapping. For the former case, the depth texture is not setup with `TEXTURE_BINDING` usage in general (in the absence of `DepthPrepass`).
So the requirement `OcclusionCulling => DepthPrepass` is somewhat indirectly enforced via `MipGenerationPlugin` (of course used for the implementation of `OcclusionCulling`, but also available for general purpose mipmap generation). As a side note, this plugin might be a little too eager to do work even when it is not actually used.
It also seems that this requirement can be lifted by adding the `TEXTURE_BINDING` usage when necessary, as suggested by the error, and adding this [here](https://github.com/bevyengine/bevy/blob/44ae8e2416e5ae3f97cad0e66b73ccd987bb0f3e/crates/bevy_core_pipeline/src/core_3d/mod.rs#L613)
```
pub fn prepare_core_3d_depth_textures(
mut commands: Commands,
mut texture_cache: ResMut,
render_device: Res,
views_3d: Query<(
Entity,
&ExtractedCamera,
Option<&DepthPrepass>,
&Camera3d,
Option<&OcclusionCulling>,
&Msaa,
)>,
)
...
if depth_prepass.is_some() {
// Required to read the output of the prepass
usage |= TextureUsages::COPY_SRC;
} else {
if occlusion_culling.is_some() {
usage |= TextureUsages::TEXTURE_BINDING;
}
}
...
```
I don't claim this is a correct solution, it just confirms the issue. Adding these lines fixes the crash and the `occclusion_culling` example then works even without `DepthPrepass`.
### Reproduction
To reproduce the error mentioned above, either
1. Add `OcclusionCulling` to a one of the 3d examples, e.g. [`3d_shapes`](https://github.com/bevyengine/bevy/blob/44ae8e2416e5ae3f97cad0e66b73ccd987bb0f3e/examples/3d/3d_shapes.rs#L191):
```
commands.spawn((
Camera3d::default(),
Transform::from_xyz(0.0, 7., 14.0).looking_at(Vec3::new(0., 1., 0.), Vec3::Y),
bevy_render::occlusion_culling::OcclusionCulling,
));
```
or
2. Comment out ```DepthPrepass``` insertion in [`examples/3d/occlusion_culling.rs`](https://github.com/bevyengine/bevy/blob/44ae8e2416e5ae3f97cad0e66b73ccd987bb0f3e/examples/3d/occlusion_culling.rs#L371)
https://github.com/bevyengine/bevy/blob/44ae8e2416e5ae3f97cad0e66b73ccd987bb0f3e/examples/3d/occlusion_culling.rs#L371
Contributor guide
Research direction
Start in crates/bevy_core_pipeline/src/core_3d/mod.rs, especially prepare_core_3d_depth_textures, and inspect how MipGenerationPlugin invokes prepare_downsample_depth_view_bind_groups. Reproduce with the 3d_shapes or examples/3d/occlusion_culling.rs cases after removing DepthPrepass. Done means OcclusionCulling without DepthPrepass no longer crashes and the relevant example runs successfully.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- computer-graphics, game-dev
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100