 06bf928927
			
		
	
	
		06bf928927
		
			
		
	
	
	
	
		
			
			# 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 <alice.i.cecile@gmail.com>
		
			
				
	
	
		
			88 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
			
		
		
	
	
			88 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
| //! 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()
 | |
|             },
 | |
|         );
 | |
|     }
 | |
| }
 |