-
-
Notifications
You must be signed in to change notification settings - Fork 3.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Option to enable deterministic rendering (#11248)
# Objective Issue #10243: rendering multiple triangles in the same place results in flickering. ## Solution Considered these alternatives: - `depth_bias` may not work, because of high number of entities, so creating a material per entity is practically not possible - rendering at slightly different positions does not work, because when camera is far, float rounding causes the same issues (edit: assuming we have to use the same `depth_bias`) - considered implementing deterministic operation like `query.par_iter().flat_map(...).collect()` to be used in `check_visibility` system (which would solve the issue since query is deterministic), and could not figure out how to make it as cheap as current approach with thread-local collectors (#11249) So adding an option to sort entities after `check_visibility` system run. Should not be too bad, because after visibility check, only a handful entities remain. This is probably not the only source of non-determinism in Bevy, but this is one I could find so far. At least it fixes the repro example. ## Changelog - `DeterministicRenderingConfig` option to enable deterministic rendering ## Test <img width="1392" alt="image" src="https://github.com/bevyengine/bevy/assets/28969/c735bce1-3a71-44cd-8677-c19f6c0ee6bd"> --------- Co-authored-by: Alice Cecile <[email protected]>
- Loading branch information
1 parent
9c972f0
commit 06bf928
Showing
6 changed files
with
124 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
use bevy_ecs::system::Resource; | ||
|
||
/// Configure deterministic rendering to fix flickering due to z-fighting. | ||
#[derive(Resource, Default)] | ||
pub struct DeterministicRenderingConfig { | ||
/// Sort visible entities by id before rendering to avoid flickering. | ||
/// | ||
/// Render is parallel by default, and if there's z-fighting, it may cause flickering. | ||
/// Default fix for the issue is to set `depth_bias` per material. | ||
/// When it is not possible, entities sorting can be used. | ||
/// | ||
/// This option costs performance and disabled by default. | ||
pub stable_sort_z_fighting: bool, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
//! Shows how to enable deterministic rendering which helps with flickering due to z-fighting. | ||
//! Rendering is not deterministic by default. | ||
//! Note most users don't need rendering to be deterministic, and should rely on depth bias instead. | ||
use bevy::app::App; | ||
use bevy::app::Startup; | ||
use bevy::prelude::shape::Plane; | ||
use bevy::prelude::*; | ||
use bevy::render::deterministic::DeterministicRenderingConfig; | ||
|
||
fn main() { | ||
App::new() | ||
.add_plugins(DefaultPlugins) | ||
.add_systems(Startup, setup) | ||
.add_systems(Update, (keys, update_help).chain()) | ||
.run(); | ||
} | ||
|
||
fn setup( | ||
mut commands: Commands, | ||
mut materials: ResMut<Assets<StandardMaterial>>, | ||
mut meshes: ResMut<Assets<Mesh>>, | ||
mut deterministic_rendering_config: ResMut<DeterministicRenderingConfig>, | ||
) { | ||
// Safe default. | ||
deterministic_rendering_config.stable_sort_z_fighting = true; | ||
|
||
// Help message will be rendered there. | ||
commands.spawn(TextBundle::default()); | ||
|
||
commands.spawn(Camera3dBundle { | ||
transform: Transform::from_xyz(3.0, 3.0, 3.0).looking_at(Vec3::new(0., 0., 0.), Vec3::Y), | ||
..default() | ||
}); | ||
|
||
let mesh = meshes.add(Plane::from_size(2.0)); | ||
for i in 0..360 { | ||
let color = Color::hsl(i as f32, 1.0, 0.5); | ||
commands.spawn(PbrBundle { | ||
mesh: mesh.clone(), | ||
material: materials.add(StandardMaterial { | ||
base_color: color, | ||
// Setting depth bias would be a default choice to fix z-fighting. | ||
// When it is not possible, deterministic rendering can be used. | ||
// Here we intentionally don't use depth bias to demonstrate the issue. | ||
depth_bias: 0.0, | ||
unlit: true, | ||
..Default::default() | ||
}), | ||
..default() | ||
}); | ||
} | ||
} | ||
|
||
fn keys( | ||
mut deterministic_rendering_config: ResMut<DeterministicRenderingConfig>, | ||
keyboard_input: Res<ButtonInput<KeyCode>>, | ||
) { | ||
if keyboard_input.just_pressed(KeyCode::KeyD) { | ||
deterministic_rendering_config.stable_sort_z_fighting ^= true; | ||
} | ||
} | ||
|
||
fn update_help( | ||
mut text: Query<&mut Text>, | ||
deterministic_rendering_config: Res<DeterministicRenderingConfig>, | ||
) { | ||
if deterministic_rendering_config.is_changed() { | ||
*text.single_mut() = Text::from_section( | ||
format!( | ||
"\ | ||
Press D to enable/disable deterministic rendering\n\ | ||
\n\ | ||
Deterministic rendering: {}\n\ | ||
\n\ | ||
When rendering is not deterministic, you may notice flickering due to z-fighting\n\ | ||
\n\ | ||
Warning: may cause seizures for people with photosensitive epilepsy", | ||
deterministic_rendering_config.stable_sort_z_fighting | ||
), | ||
TextStyle { | ||
font_size: 20., | ||
..default() | ||
}, | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters