bevyengine / bevyengine/bevy

`DepthPrepass` causes issues with transparent pixels

Open
#18,928 0 comments 0 reactions 0 assignees View on GitHub
A-Rendering C-Bug S-Needs-Investigation
Dominant language
Rust
Stars
48.2k
Forks
4.8k
Avg merge
3d 22h
Merged PRs (30d)
161

Description

## Bevy version

Bevy v0.16.0

## Relevant system information

```
2025-04-25T04:39:35.317159Z INFO bevy_render::renderer: AdapterInfo { name: "AMD Radeon RX 7900 XT", vendor: 4098, device: 29772, device_type: DiscreteGpu, driver: "AMD proprietary driver", driver_info: "25.3.1 (LLPC)", backend: Vulkan }
2025-04-25T04:39:35.472280Z INFO bevy_render::batching::gpu_preprocessing: GPU preprocessing is fully supported on this device
```

## What you did

Loading a model with textures that use alpha with `DepthPrepass` enabled on the camera causes semi-transparent "pixels" to not render and pass through the background.

## What went wrong

See images below, it causes very broken rendering both with and without OIT enabled.

## Additional information

```rs
use bevy::core_pipeline::oit::OrderIndependentTransparencySettings;
use bevy::core_pipeline::prepass::DepthPrepass;
use bevy::core_pipeline::tonemapping::Tonemapping;
use bevy::prelude::*;
use bevy_asset_loader::asset_collection::AssetCollection;
use bevy_asset_loader::loading_state::config::ConfigureLoadingState;
use bevy_asset_loader::loading_state::{LoadingState, LoadingStateAppExt};
use orthrus_panda3d::bevy2::{Panda3DPlugin, Panda3DSource, PandaAsset};

#[derive(States, Debug, Clone, Copy, Eq, PartialEq, Hash, Default)]
enum MyStates {
#[default]
AssetLoading,
Next,
}

fn main() {
App::new()
.add_plugins(Panda3DSource)
.add_plugins(DefaultPlugins)
.add_plugins(Panda3DPlugin)
.init_state::()
.add_loading_state(
LoadingState::new(MyStates::AssetLoading)
.continue_to_state(MyStates::Next)
.load_collection::(),
)
.add_systems(OnEnter(MyStates::Next), setup)
.run();
}

#[derive(AssetCollection, Resource)]
struct ToontownAssets {
#[asset(path = "phase_3/models/char/tt_a_chr_dgl_shorts_head_1000.bam")]
toon_head: Handle,
}

/// set up a simple 3D scene
fn setup(
mut commands: Commands, assets: Res,
panda3d_assets: Res>, mut scene_spawner: ResMut,
) {
let model = panda3d_assets.get(&assets.toon_head).unwrap();
scene_spawner.spawn(model.scene.clone());

// light
commands.spawn((
PointLight { shadows_enabled: true, ..default() },
Transform::from_xyz(4.0, 8.0, 4.0),
));
// camera
commands.spawn((
Camera3d::default(),
Tonemapping::None,
Transform::from_xyz(-2.0, 3.0, 2.0).looking_at(Vec3::new(0.0, 0.0, 0.0), Vec3::Z),
OrderIndependentTransparencySettings::default(),
Msaa::Off,
DepthPrepass,
));
}
```

When loading with only OIT (or with no attributes), it renders fine:
![Image](https://github.com/user-attachments/assets/588e4101-8979-495d-b708-66e99eb000c0)
However, when both OIT and `DepthPrepass` are enabled, it causes rendering artifacts:
![Image](https://github.com/user-attachments/assets/d62fc1ed-b175-484b-af77-72fbe7c45e74)
Note that the pupils are a different mesh than the eyes, and they also experience artifacts (see the white part of the eye). If this wasn't a requirement for Forward Decals, it wouldn't be such a deal-breaker.

Additionally, DepthPrepass on its own causes even more issues:
![Image](https://github.com/user-attachments/assets/dc1c73af-6c40-4517-adae-eebc58bc6d2e)

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.