mirror of
https://github.com/bevyengine/bevy.git
synced 2026-05-06 06:06:42 -04:00
Split AmbientLight into two (#21595)
# Objective For resources-as-components (#19731), structs mustn't doubly derive both `Component` and `Resource`. ## Solution Split `AmbientLight` in two: `AmbientLight` (the resource) and `AmbientLightOverride` (the component). ## Testing I initially made two structs `AmbientLightComponent` and `AmbientLightResource`, and replaced every mention with the relevant one to ensure that I didn't confuse the two. ## Notes - I don't know if the names are correct. I kept the easiest name for the resource, as that's the one most often used. - I haven't provided any conversion methods as there are already plans to replace the component variant with something else. --------- Co-authored-by: atlv <email@atlasdostal.com>
This commit is contained in:
@@ -5,25 +5,9 @@ use bevy_reflect::prelude::*;
|
||||
|
||||
/// An ambient light, which lights the entire scene equally.
|
||||
///
|
||||
/// This resource is inserted by the [`LightPlugin`] and by default it is set to a low ambient light.
|
||||
///
|
||||
/// It can also be added to a camera to override the resource (or default) ambient for that camera only.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Make ambient light slightly brighter:
|
||||
///
|
||||
/// ```
|
||||
/// # use bevy_ecs::system::ResMut;
|
||||
/// # use bevy_light::AmbientLight;
|
||||
/// fn setup_ambient_light(mut ambient_light: ResMut<AmbientLight>) {
|
||||
/// ambient_light.brightness = 100.0;
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// [`LightPlugin`]: crate::LightPlugin
|
||||
#[derive(Resource, Component, Clone, Debug, Reflect)]
|
||||
#[reflect(Resource, Component, Debug, Default, Clone)]
|
||||
/// It can be added to a camera to override [`GlobalAmbientLight`], which is the default that is otherwise used.
|
||||
#[derive(Component, Clone, Debug, Reflect)]
|
||||
#[reflect(Component, Debug, Default, Clone)]
|
||||
#[require(Camera)]
|
||||
pub struct AmbientLight {
|
||||
pub color: Color,
|
||||
@@ -54,8 +38,57 @@ impl Default for AmbientLight {
|
||||
}
|
||||
}
|
||||
|
||||
impl AmbientLight {
|
||||
pub const NONE: AmbientLight = AmbientLight {
|
||||
/// The global ambient light, which lights the entire scene equally.
|
||||
///
|
||||
/// This resource is inserted by the [`LightPlugin`] and by default it is set to a low ambient light.
|
||||
/// Inserting an [`AmbientLight`] on a camera will override this default.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Make ambient light slightly brighter:
|
||||
///
|
||||
/// ```
|
||||
/// # use bevy_ecs::system::ResMut;
|
||||
/// # use bevy_light::GlobalAmbientLight;
|
||||
/// fn setup_ambient_light(mut ambient_light: ResMut<GlobalAmbientLight>) {
|
||||
/// ambient_light.brightness = 100.0;
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// [`LightPlugin`]: crate::LightPlugin
|
||||
#[derive(Resource, Clone, Debug, Reflect)]
|
||||
#[reflect(Resource, Debug, Default, Clone)]
|
||||
pub struct GlobalAmbientLight {
|
||||
pub color: Color,
|
||||
|
||||
/// A direct scale factor multiplied with `color` before being passed to the shader.
|
||||
///
|
||||
/// After applying this multiplier, the resulting value should be in units of [cd/m^2].
|
||||
///
|
||||
/// [cd/m^2]: https://en.wikipedia.org/wiki/Candela_per_square_metre
|
||||
pub brightness: f32,
|
||||
|
||||
/// Whether this ambient light has an effect on meshes with lightmaps.
|
||||
///
|
||||
/// Set this to false if your lightmap baking tool bakes the ambient light
|
||||
/// into the lightmaps, to avoid rendering that light twice.
|
||||
///
|
||||
/// By default, this is set to true.
|
||||
pub affects_lightmapped_meshes: bool,
|
||||
}
|
||||
|
||||
impl Default for GlobalAmbientLight {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
color: Color::WHITE,
|
||||
brightness: 80.0,
|
||||
affects_lightmapped_meshes: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl GlobalAmbientLight {
|
||||
pub const NONE: GlobalAmbientLight = GlobalAmbientLight {
|
||||
color: Color::WHITE,
|
||||
brightness: 0.0,
|
||||
affects_lightmapped_meshes: true,
|
||||
|
||||
@@ -25,7 +25,7 @@ use cluster::{
|
||||
VisibleClusterableObjects,
|
||||
};
|
||||
mod ambient_light;
|
||||
pub use ambient_light::AmbientLight;
|
||||
pub use ambient_light::{AmbientLight, GlobalAmbientLight};
|
||||
mod probe;
|
||||
pub use probe::{
|
||||
AtmosphereEnvironmentMapLight, EnvironmentMapLight, GeneratedEnvironmentMapLight,
|
||||
@@ -58,7 +58,7 @@ pub mod prelude {
|
||||
#[doc(hidden)]
|
||||
pub use crate::{
|
||||
light_consts, AmbientLight, DirectionalLight, EnvironmentMapLight,
|
||||
GeneratedEnvironmentMapLight, LightProbe, PointLight, SpotLight,
|
||||
GeneratedEnvironmentMapLight, GlobalAmbientLight, LightProbe, PointLight, SpotLight,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -133,7 +133,7 @@ pub struct LightPlugin;
|
||||
impl Plugin for LightPlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
app.init_resource::<GlobalVisibleClusterableObjects>()
|
||||
.init_resource::<AmbientLight>()
|
||||
.init_resource::<GlobalAmbientLight>()
|
||||
.init_resource::<DirectionalLightShadowMap>()
|
||||
.init_resource::<PointLightShadowMap>()
|
||||
.configure_sets(
|
||||
|
||||
@@ -25,8 +25,8 @@ use bevy_light::cluster::GlobalVisibleClusterableObjects;
|
||||
use bevy_light::SunDisk;
|
||||
use bevy_light::{
|
||||
spot_light_clip_from_view, spot_light_world_from_view, AmbientLight, CascadeShadowConfig,
|
||||
Cascades, DirectionalLight, DirectionalLightShadowMap, NotShadowCaster, PointLight,
|
||||
PointLightShadowMap, ShadowFilteringMethod, SpotLight, VolumetricLight,
|
||||
Cascades, DirectionalLight, DirectionalLightShadowMap, GlobalAmbientLight, NotShadowCaster,
|
||||
PointLight, PointLightShadowMap, ShadowFilteringMethod, SpotLight, VolumetricLight,
|
||||
};
|
||||
use bevy_math::{ops, Mat4, UVec4, Vec3, Vec3Swizzles, Vec4, Vec4Swizzles};
|
||||
use bevy_platform::collections::{HashMap, HashSet};
|
||||
@@ -248,8 +248,8 @@ pub fn extract_shadow_filtering_method(
|
||||
// foreign trait ExtractResource on foreign type AmbientLight
|
||||
pub fn extract_ambient_light_resource(
|
||||
mut commands: Commands,
|
||||
main_resource: Extract<Option<Res<AmbientLight>>>,
|
||||
target_resource: Option<ResMut<AmbientLight>>,
|
||||
main_resource: Extract<Option<Res<GlobalAmbientLight>>>,
|
||||
target_resource: Option<ResMut<GlobalAmbientLight>>,
|
||||
) {
|
||||
if let Some(main_resource) = main_resource.as_ref() {
|
||||
if let Some(mut target_resource) = target_resource {
|
||||
@@ -720,7 +720,7 @@ pub fn prepare_lights(
|
||||
),
|
||||
With<Camera3d>,
|
||||
>,
|
||||
ambient_light: Res<AmbientLight>,
|
||||
ambient_light: Res<GlobalAmbientLight>,
|
||||
point_light_shadow_map: Res<PointLightShadowMap>,
|
||||
directional_light_shadow_map: Res<DirectionalLightShadowMap>,
|
||||
mut shadow_render_phases: ResMut<ViewBinnedRenderPhases<Shadow>>,
|
||||
@@ -1150,6 +1150,11 @@ pub fn prepare_lights(
|
||||
);
|
||||
|
||||
let n_clusters = clusters.dimensions.x * clusters.dimensions.y * clusters.dimensions.z;
|
||||
let ambient_light = AmbientLight {
|
||||
color: ambient_light.color,
|
||||
brightness: ambient_light.brightness,
|
||||
affects_lightmapped_meshes: ambient_light.affects_lightmapped_meshes,
|
||||
};
|
||||
let ambient_light = maybe_ambient_override.unwrap_or(&ambient_light);
|
||||
|
||||
let mut gpu_directional_lights = [GpuDirectionalLight::default(); MAX_DIRECTIONAL_LIGHTS];
|
||||
|
||||
@@ -97,7 +97,7 @@ fn setup(
|
||||
}
|
||||
}
|
||||
|
||||
commands.insert_resource(AmbientLight {
|
||||
commands.insert_resource(GlobalAmbientLight {
|
||||
color: Color::WHITE,
|
||||
brightness: 0.0,
|
||||
..default()
|
||||
|
||||
+1
-1
@@ -29,7 +29,7 @@ use bevy::{
|
||||
|
||||
fn main() {
|
||||
App::new()
|
||||
.insert_resource(AmbientLight::NONE)
|
||||
.insert_resource(GlobalAmbientLight::NONE)
|
||||
.add_plugins(DefaultPlugins)
|
||||
.add_systems(
|
||||
Startup,
|
||||
|
||||
@@ -22,7 +22,7 @@ fn main() {
|
||||
}),
|
||||
..default()
|
||||
}))
|
||||
.insert_resource(AmbientLight::NONE)
|
||||
.insert_resource(GlobalAmbientLight::NONE)
|
||||
.add_systems(Startup, setup)
|
||||
.add_systems(Update, rotate_camera)
|
||||
.run();
|
||||
|
||||
@@ -157,7 +157,7 @@ fn main() {
|
||||
.add_plugins(MaterialPlugin::<VoxelVisualizationMaterial>::default())
|
||||
.init_resource::<AppStatus>()
|
||||
.init_resource::<ExampleAssets>()
|
||||
.insert_resource(AmbientLight {
|
||||
.insert_resource(GlobalAmbientLight {
|
||||
color: Color::WHITE,
|
||||
brightness: 0.0,
|
||||
..default()
|
||||
@@ -414,7 +414,7 @@ fn toggle_irradiance_volumes(
|
||||
light_probe_query: Query<Entity, With<LightProbe>>,
|
||||
mut app_status: ResMut<AppStatus>,
|
||||
assets: Res<ExampleAssets>,
|
||||
mut ambient_light: ResMut<AmbientLight>,
|
||||
mut ambient_light: ResMut<GlobalAmbientLight>,
|
||||
) {
|
||||
if !keyboard.just_pressed(KeyCode::Space) {
|
||||
return;
|
||||
|
||||
@@ -120,7 +120,7 @@ fn setup(
|
||||
|
||||
// ambient light
|
||||
// ambient lights' brightnesses are measured in candela per meter square, calculable as (color * brightness)
|
||||
commands.insert_resource(AmbientLight {
|
||||
commands.insert_resource(GlobalAmbientLight {
|
||||
color: ORANGE_RED.into(),
|
||||
brightness: 200.0,
|
||||
..default()
|
||||
@@ -290,7 +290,7 @@ fn update_exposure(
|
||||
|
||||
fn toggle_ambient_light(
|
||||
key_input: Res<ButtonInput<KeyCode>>,
|
||||
mut ambient_light: ResMut<AmbientLight>,
|
||||
mut ambient_light: ResMut<GlobalAmbientLight>,
|
||||
text: Single<Entity, With<Text>>,
|
||||
mut writer: TextUiWriter,
|
||||
) {
|
||||
|
||||
@@ -27,7 +27,7 @@ fn main() {
|
||||
|
||||
let mut app = App::new();
|
||||
app.add_plugins(DefaultPlugins)
|
||||
.insert_resource(AmbientLight::NONE);
|
||||
.insert_resource(GlobalAmbientLight::NONE);
|
||||
|
||||
if args.deferred {
|
||||
app.insert_resource(DefaultOpaqueRendererMethod::deferred());
|
||||
|
||||
@@ -124,7 +124,7 @@ fn main() {
|
||||
..default()
|
||||
}))
|
||||
.add_plugins(MeshPickingPlugin)
|
||||
.insert_resource(AmbientLight {
|
||||
.insert_resource(GlobalAmbientLight {
|
||||
color: ClearColor::default().0,
|
||||
brightness: 10000.0,
|
||||
affects_lightmapped_meshes: true,
|
||||
|
||||
@@ -57,7 +57,7 @@ fn setup_scene(
|
||||
mut meshes: ResMut<Assets<Mesh>>,
|
||||
mut materials: ResMut<Assets<StandardMaterial>>,
|
||||
) {
|
||||
commands.insert_resource(AmbientLight {
|
||||
commands.insert_resource(GlobalAmbientLight {
|
||||
color: Color::WHITE,
|
||||
brightness: 300.0,
|
||||
..default()
|
||||
|
||||
@@ -85,7 +85,7 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
|
||||
// ambient light
|
||||
// NOTE: The ambient light is used to scale how bright the environment map is so with a bright
|
||||
// environment map, use an appropriate color and brightness to match
|
||||
commands.insert_resource(AmbientLight {
|
||||
commands.insert_resource(GlobalAmbientLight {
|
||||
color: Color::srgb_u8(210, 220, 240),
|
||||
brightness: 1.0,
|
||||
..default()
|
||||
|
||||
@@ -59,7 +59,7 @@ fn main() {
|
||||
}))
|
||||
.init_resource::<AppAssets>()
|
||||
.init_resource::<AppStatus>()
|
||||
.insert_resource(AmbientLight {
|
||||
.insert_resource(GlobalAmbientLight {
|
||||
color: Color::BLACK,
|
||||
brightness: 0.0,
|
||||
..default()
|
||||
|
||||
@@ -4,7 +4,7 @@ use bevy::prelude::*;
|
||||
|
||||
fn main() {
|
||||
App::new()
|
||||
.insert_resource(AmbientLight {
|
||||
.insert_resource(GlobalAmbientLight {
|
||||
brightness: 60.0,
|
||||
..default()
|
||||
})
|
||||
|
||||
@@ -21,7 +21,7 @@ Rotate Camera: Left and Right Arrows";
|
||||
|
||||
fn main() {
|
||||
App::new()
|
||||
.insert_resource(AmbientLight {
|
||||
.insert_resource(GlobalAmbientLight {
|
||||
brightness: 20.0,
|
||||
..default()
|
||||
})
|
||||
|
||||
+1
-1
@@ -11,7 +11,7 @@ use std::f32::consts::PI;
|
||||
|
||||
fn main() {
|
||||
App::new()
|
||||
.insert_resource(AmbientLight {
|
||||
.insert_resource(GlobalAmbientLight {
|
||||
brightness: 1000.,
|
||||
..default()
|
||||
})
|
||||
|
||||
@@ -47,7 +47,7 @@ fn main() {
|
||||
.add_plugins(DefaultPlugins)
|
||||
.insert_resource(ClearColor(Color::BLACK))
|
||||
.insert_resource(PointLightShadowMap { size: 2048 })
|
||||
.insert_resource(AmbientLight {
|
||||
.insert_resource(GlobalAmbientLight {
|
||||
brightness: 0.0,
|
||||
..default()
|
||||
})
|
||||
|
||||
@@ -47,7 +47,7 @@ fn main() {
|
||||
blue: 0.02,
|
||||
alpha: 1.0,
|
||||
})))
|
||||
.insert_resource(AmbientLight::NONE)
|
||||
.insert_resource(GlobalAmbientLight::NONE)
|
||||
.init_resource::<AppSettings>()
|
||||
.add_systems(Startup, setup)
|
||||
.add_systems(Update, tweak_scene)
|
||||
|
||||
@@ -9,7 +9,7 @@ const GLTF_PATH: &str = "models/animated/Fox.glb";
|
||||
|
||||
fn main() {
|
||||
App::new()
|
||||
.insert_resource(AmbientLight {
|
||||
.insert_resource(GlobalAmbientLight {
|
||||
color: Color::WHITE,
|
||||
brightness: 2000.,
|
||||
..default()
|
||||
|
||||
@@ -8,7 +8,7 @@ const FOX_PATH: &str = "models/animated/Fox.glb";
|
||||
|
||||
fn main() {
|
||||
App::new()
|
||||
.insert_resource(AmbientLight {
|
||||
.insert_resource(GlobalAmbientLight {
|
||||
color: Color::WHITE,
|
||||
brightness: 2000.,
|
||||
..default()
|
||||
|
||||
@@ -15,7 +15,7 @@ const FOX_PATH: &str = "models/animated/Fox.glb";
|
||||
|
||||
fn main() {
|
||||
App::new()
|
||||
.insert_resource(AmbientLight {
|
||||
.insert_resource(GlobalAmbientLight {
|
||||
color: Color::WHITE,
|
||||
brightness: 2000.,
|
||||
..default()
|
||||
|
||||
@@ -10,7 +10,7 @@ use bevy::{
|
||||
fn main() {
|
||||
App::new()
|
||||
.add_plugins(DefaultPlugins)
|
||||
.insert_resource(AmbientLight {
|
||||
.insert_resource(GlobalAmbientLight {
|
||||
color: Color::WHITE,
|
||||
brightness: 150.0,
|
||||
..default()
|
||||
|
||||
@@ -88,7 +88,7 @@ fn main() {
|
||||
(handle_weight_drag, update_ui, sync_weights).chain(),
|
||||
)
|
||||
.insert_resource(args)
|
||||
.insert_resource(AmbientLight {
|
||||
.insert_resource(GlobalAmbientLight {
|
||||
color: WHITE.into(),
|
||||
brightness: 100.0,
|
||||
..default()
|
||||
|
||||
@@ -105,7 +105,7 @@ fn main() {
|
||||
.add_systems(Update, setup_animation_graph_once_loaded)
|
||||
.add_systems(Update, handle_button_toggles)
|
||||
.add_systems(Update, update_ui)
|
||||
.insert_resource(AmbientLight {
|
||||
.insert_resource(GlobalAmbientLight {
|
||||
color: WHITE.into(),
|
||||
brightness: 100.0,
|
||||
..default()
|
||||
|
||||
@@ -18,7 +18,7 @@ use rand_chacha::ChaCha8Rng;
|
||||
fn main() {
|
||||
App::new()
|
||||
.add_plugins(DefaultPlugins)
|
||||
.insert_resource(AmbientLight {
|
||||
.insert_resource(GlobalAmbientLight {
|
||||
brightness: 3000.0,
|
||||
..default()
|
||||
})
|
||||
|
||||
@@ -10,7 +10,7 @@ const GLTF_PATH: &str = "models/animated/MorphStressTest.gltf";
|
||||
fn main() {
|
||||
App::new()
|
||||
.add_plugins(DefaultPlugins)
|
||||
.insert_resource(AmbientLight {
|
||||
.insert_resource(GlobalAmbientLight {
|
||||
brightness: 150.0,
|
||||
..default()
|
||||
})
|
||||
|
||||
@@ -17,7 +17,7 @@ fn main() {
|
||||
App::new()
|
||||
.add_plugins(DefaultPlugins)
|
||||
.init_state::<LoadingState>()
|
||||
.insert_resource(AmbientLight {
|
||||
.insert_resource(GlobalAmbientLight {
|
||||
color: Color::WHITE,
|
||||
brightness: 2000.,
|
||||
..default()
|
||||
|
||||
@@ -23,7 +23,7 @@ const ATTRIBUTE_BARYCENTRIC: MeshVertexAttribute =
|
||||
|
||||
fn main() {
|
||||
App::new()
|
||||
.insert_resource(AmbientLight {
|
||||
.insert_resource(GlobalAmbientLight {
|
||||
color: Color::WHITE,
|
||||
brightness: 1.0 / 5.0f32,
|
||||
..default()
|
||||
|
||||
@@ -8,7 +8,7 @@ use bevy::{math::ops, mesh::skinning::SkinnedMesh, prelude::*};
|
||||
fn main() {
|
||||
App::new()
|
||||
.add_plugins(DefaultPlugins)
|
||||
.insert_resource(AmbientLight {
|
||||
.insert_resource(GlobalAmbientLight {
|
||||
brightness: 750.0,
|
||||
..default()
|
||||
})
|
||||
|
||||
@@ -306,7 +306,7 @@ fn setup_cameras(mut commands: Commands) {
|
||||
));
|
||||
}
|
||||
|
||||
fn setup_ambient_light(mut ambient_light: ResMut<AmbientLight>) {
|
||||
fn setup_ambient_light(mut ambient_light: ResMut<GlobalAmbientLight>) {
|
||||
ambient_light.brightness = 50.0;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
---
|
||||
title: "`AmbientLight` split into a component and a resource"
|
||||
pull_requests: [21585]
|
||||
---
|
||||
|
||||
The `AmbientLight` used to be both a component *and* a resource.
|
||||
In 0.18, we've split this in two separate structs: `AmbientLight` and `GlobalAmbientLight`.
|
||||
The resource `GlobalAmbientLight` is the default ambient light for the entire world and automatically added by `LightPlugin`.
|
||||
Meanwhile, `AmbientLight` is a component that can be added to a `Camera` in order to override the default `GlobalAmbientLight`.
|
||||
When appropriate, rename `AmbientLight` to `GlobalAmbientLight`.
|
||||
|
||||
Before:
|
||||
|
||||
```rust
|
||||
app.insert_resource(AmbientLight {
|
||||
color: Color::WHITE,
|
||||
brightness: 2000.,
|
||||
..default()
|
||||
});
|
||||
```
|
||||
|
||||
After:
|
||||
|
||||
```rust
|
||||
app.insert_resource(GlobalAmbientLight {
|
||||
color: Color::WHITE,
|
||||
brightness: 2000.,
|
||||
..default()
|
||||
});
|
||||
```
|
||||
@@ -16,7 +16,7 @@ use core::f32::consts::TAU;
|
||||
fn main() {
|
||||
App::new()
|
||||
.add_plugins(DefaultPlugins)
|
||||
.insert_resource(AmbientLight {
|
||||
.insert_resource(GlobalAmbientLight {
|
||||
brightness: 20_000.0,
|
||||
..default()
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user