 1d8d78ef0e
			
		
	
	
		1d8d78ef0e
		
			
		
	
	
	
	
		
			
			The `ClearColor` PR was merged before I was quite finished. This fixes a few errors, and addresses Cart's feedback about the pixel perfect example by updating the sprite colors to match the existing bevy bird branding colors. 
		
			
				
	
	
		
			209 lines
		
	
	
		
			7.2 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
			
		
		
	
	
			209 lines
		
	
	
		
			7.2 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
| //! Illustrates bloom post-processing in 2d.
 | |
| 
 | |
| use bevy::{
 | |
|     core_pipeline::{
 | |
|         bloom::{BloomCompositeMode, BloomSettings},
 | |
|         tonemapping::Tonemapping,
 | |
|     },
 | |
|     prelude::*,
 | |
|     sprite::MaterialMesh2dBundle,
 | |
| };
 | |
| 
 | |
| fn main() {
 | |
|     App::new()
 | |
|         .add_plugins(DefaultPlugins)
 | |
|         .add_systems(Startup, setup)
 | |
|         .add_systems(Update, update_bloom_settings)
 | |
|         .run();
 | |
| }
 | |
| 
 | |
| fn setup(
 | |
|     mut commands: Commands,
 | |
|     mut meshes: ResMut<Assets<Mesh>>,
 | |
|     mut materials: ResMut<Assets<ColorMaterial>>,
 | |
|     asset_server: Res<AssetServer>,
 | |
| ) {
 | |
|     commands.spawn((
 | |
|         Camera2dBundle {
 | |
|             camera: Camera {
 | |
|                 hdr: true, // 1. HDR is required for bloom
 | |
|                 ..default()
 | |
|             },
 | |
|             tonemapping: Tonemapping::TonyMcMapface, // 2. Using a tonemapper that desaturates to white is recommended
 | |
|             ..default()
 | |
|         },
 | |
|         BloomSettings::default(), // 3. Enable bloom for the camera
 | |
|     ));
 | |
| 
 | |
|     // Sprite
 | |
|     commands.spawn(SpriteBundle {
 | |
|         texture: asset_server.load("branding/bevy_bird_dark.png"),
 | |
|         sprite: Sprite {
 | |
|             color: Color::rgb(5.0, 5.0, 5.0), // 4. Put something bright in a dark environment to see the effect
 | |
|             custom_size: Some(Vec2::splat(160.0)),
 | |
|             ..default()
 | |
|         },
 | |
|         ..default()
 | |
|     });
 | |
| 
 | |
|     // Circle mesh
 | |
|     commands.spawn(MaterialMesh2dBundle {
 | |
|         mesh: meshes.add(shape::Circle::new(100.).into()).into(),
 | |
|         // 4. Put something bright in a dark environment to see the effect
 | |
|         material: materials.add(ColorMaterial::from(Color::rgb(7.5, 0.0, 7.5))),
 | |
|         transform: Transform::from_translation(Vec3::new(-200., 0., 0.)),
 | |
|         ..default()
 | |
|     });
 | |
| 
 | |
|     // Hexagon mesh
 | |
|     commands.spawn(MaterialMesh2dBundle {
 | |
|         mesh: meshes
 | |
|             .add(shape::RegularPolygon::new(100., 6).into())
 | |
|             .into(),
 | |
|         // 4. Put something bright in a dark environment to see the effect
 | |
|         material: materials.add(ColorMaterial::from(Color::rgb(6.25, 9.4, 9.1))),
 | |
|         transform: Transform::from_translation(Vec3::new(200., 0., 0.)),
 | |
|         ..default()
 | |
|     });
 | |
| 
 | |
|     // UI
 | |
|     commands.spawn(
 | |
|         TextBundle::from_section(
 | |
|             "",
 | |
|             TextStyle {
 | |
|                 font_size: 18.0,
 | |
|                 color: Color::WHITE,
 | |
|                 ..default()
 | |
|             },
 | |
|         )
 | |
|         .with_style(Style {
 | |
|             position_type: PositionType::Absolute,
 | |
|             bottom: Val::Px(10.0),
 | |
|             left: Val::Px(10.0),
 | |
|             ..default()
 | |
|         }),
 | |
|     );
 | |
| }
 | |
| 
 | |
| // ------------------------------------------------------------------------------------------------
 | |
| 
 | |
| fn update_bloom_settings(
 | |
|     mut camera: Query<(Entity, Option<&mut BloomSettings>), With<Camera>>,
 | |
|     mut text: Query<&mut Text>,
 | |
|     mut commands: Commands,
 | |
|     keycode: Res<Input<KeyCode>>,
 | |
|     time: Res<Time>,
 | |
| ) {
 | |
|     let bloom_settings = camera.single_mut();
 | |
|     let mut text = text.single_mut();
 | |
|     let text = &mut text.sections[0].value;
 | |
| 
 | |
|     match bloom_settings {
 | |
|         (entity, Some(mut bloom_settings)) => {
 | |
|             *text = "BloomSettings (Toggle: Space)\n".to_string();
 | |
|             text.push_str(&format!("(Q/A) Intensity: {}\n", bloom_settings.intensity));
 | |
|             text.push_str(&format!(
 | |
|                 "(W/S) Low-frequency boost: {}\n",
 | |
|                 bloom_settings.low_frequency_boost
 | |
|             ));
 | |
|             text.push_str(&format!(
 | |
|                 "(E/D) Low-frequency boost curvature: {}\n",
 | |
|                 bloom_settings.low_frequency_boost_curvature
 | |
|             ));
 | |
|             text.push_str(&format!(
 | |
|                 "(R/F) High-pass frequency: {}\n",
 | |
|                 bloom_settings.high_pass_frequency
 | |
|             ));
 | |
|             text.push_str(&format!(
 | |
|                 "(T/G) Mode: {}\n",
 | |
|                 match bloom_settings.composite_mode {
 | |
|                     BloomCompositeMode::EnergyConserving => "Energy-conserving",
 | |
|                     BloomCompositeMode::Additive => "Additive",
 | |
|                 }
 | |
|             ));
 | |
|             text.push_str(&format!(
 | |
|                 "(Y/H) Threshold: {}\n",
 | |
|                 bloom_settings.prefilter_settings.threshold
 | |
|             ));
 | |
|             text.push_str(&format!(
 | |
|                 "(U/J) Threshold softness: {}\n",
 | |
|                 bloom_settings.prefilter_settings.threshold_softness
 | |
|             ));
 | |
| 
 | |
|             if keycode.just_pressed(KeyCode::Space) {
 | |
|                 commands.entity(entity).remove::<BloomSettings>();
 | |
|             }
 | |
| 
 | |
|             let dt = time.delta_seconds();
 | |
| 
 | |
|             if keycode.pressed(KeyCode::A) {
 | |
|                 bloom_settings.intensity -= dt / 10.0;
 | |
|             }
 | |
|             if keycode.pressed(KeyCode::Q) {
 | |
|                 bloom_settings.intensity += dt / 10.0;
 | |
|             }
 | |
|             bloom_settings.intensity = bloom_settings.intensity.clamp(0.0, 1.0);
 | |
| 
 | |
|             if keycode.pressed(KeyCode::S) {
 | |
|                 bloom_settings.low_frequency_boost -= dt / 10.0;
 | |
|             }
 | |
|             if keycode.pressed(KeyCode::W) {
 | |
|                 bloom_settings.low_frequency_boost += dt / 10.0;
 | |
|             }
 | |
|             bloom_settings.low_frequency_boost = bloom_settings.low_frequency_boost.clamp(0.0, 1.0);
 | |
| 
 | |
|             if keycode.pressed(KeyCode::D) {
 | |
|                 bloom_settings.low_frequency_boost_curvature -= dt / 10.0;
 | |
|             }
 | |
|             if keycode.pressed(KeyCode::E) {
 | |
|                 bloom_settings.low_frequency_boost_curvature += dt / 10.0;
 | |
|             }
 | |
|             bloom_settings.low_frequency_boost_curvature =
 | |
|                 bloom_settings.low_frequency_boost_curvature.clamp(0.0, 1.0);
 | |
| 
 | |
|             if keycode.pressed(KeyCode::F) {
 | |
|                 bloom_settings.high_pass_frequency -= dt / 10.0;
 | |
|             }
 | |
|             if keycode.pressed(KeyCode::R) {
 | |
|                 bloom_settings.high_pass_frequency += dt / 10.0;
 | |
|             }
 | |
|             bloom_settings.high_pass_frequency = bloom_settings.high_pass_frequency.clamp(0.0, 1.0);
 | |
| 
 | |
|             if keycode.pressed(KeyCode::G) {
 | |
|                 bloom_settings.composite_mode = BloomCompositeMode::Additive;
 | |
|             }
 | |
|             if keycode.pressed(KeyCode::T) {
 | |
|                 bloom_settings.composite_mode = BloomCompositeMode::EnergyConserving;
 | |
|             }
 | |
| 
 | |
|             if keycode.pressed(KeyCode::H) {
 | |
|                 bloom_settings.prefilter_settings.threshold -= dt;
 | |
|             }
 | |
|             if keycode.pressed(KeyCode::Y) {
 | |
|                 bloom_settings.prefilter_settings.threshold += dt;
 | |
|             }
 | |
|             bloom_settings.prefilter_settings.threshold =
 | |
|                 bloom_settings.prefilter_settings.threshold.max(0.0);
 | |
| 
 | |
|             if keycode.pressed(KeyCode::J) {
 | |
|                 bloom_settings.prefilter_settings.threshold_softness -= dt / 10.0;
 | |
|             }
 | |
|             if keycode.pressed(KeyCode::U) {
 | |
|                 bloom_settings.prefilter_settings.threshold_softness += dt / 10.0;
 | |
|             }
 | |
|             bloom_settings.prefilter_settings.threshold_softness = bloom_settings
 | |
|                 .prefilter_settings
 | |
|                 .threshold_softness
 | |
|                 .clamp(0.0, 1.0);
 | |
|         }
 | |
| 
 | |
|         (entity, None) => {
 | |
|             *text = "Bloom: Off (Toggle: Space)".to_string();
 | |
| 
 | |
|             if keycode.just_pressed(KeyCode::Space) {
 | |
|                 commands.entity(entity).insert(BloomSettings::default());
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| }
 |