Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New Exposure and Lighting Defaults (and calibrate examples) #11868

Merged
merged 9 commits into from
Feb 15, 2024
8 changes: 5 additions & 3 deletions crates/bevy_core_pipeline/src/core_3d/camera_3d.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::tonemapping::{DebandDither, Tonemapping};
use bevy_ecs::prelude::*;
use bevy_reflect::{Reflect, ReflectDeserialize, ReflectSerialize};
use bevy_render::{
camera::{Camera, CameraMainTextureUsages, CameraRenderGraph, Projection},
camera::{Camera, CameraMainTextureUsages, CameraRenderGraph, Exposure, Projection},
extract_component::ExtractComponent,
primitives::Frustum,
render_resource::{LoadOp, TextureUsages},
Expand Down Expand Up @@ -145,6 +145,7 @@ pub struct Camera3dBundle {
pub tonemapping: Tonemapping,
pub dither: DebandDither,
pub color_grading: ColorGrading,
pub exposure: Exposure,
pub main_texture_usages: CameraMainTextureUsages,
}

Expand All @@ -161,9 +162,10 @@ impl Default for Camera3dBundle {
global_transform: Default::default(),
camera_3d: Default::default(),
tonemapping: Default::default(),
dither: DebandDither::Enabled,
color_grading: ColorGrading::default(),
color_grading: Default::default(),
exposure: Default::default(),
main_texture_usages: Default::default(),
dither: DebandDither::Enabled,
}
}
}
12 changes: 5 additions & 7 deletions crates/bevy_core_pipeline/src/skybox/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use bevy_ecs::{
system::{Commands, Query, Res, ResMut, Resource},
};
use bevy_render::{
camera::ExposureSettings,
camera::Exposure,
extract_component::{
ComponentUniforms, DynamicUniformIndex, ExtractComponent, ExtractComponentPlugin,
UniformComponentPlugin,
Expand Down Expand Up @@ -80,16 +80,14 @@ pub struct Skybox {
}

impl ExtractComponent for Skybox {
type QueryData = (&'static Self, Option<&'static ExposureSettings>);
type QueryData = (&'static Self, Option<&'static Exposure>);
type QueryFilter = ();
type Out = (Self, SkyboxUniforms);

fn extract_component(
(skybox, exposure_settings): QueryItem<'_, Self::QueryData>,
) -> Option<Self::Out> {
let exposure = exposure_settings
fn extract_component((skybox, exposure): QueryItem<'_, Self::QueryData>) -> Option<Self::Out> {
let exposure = exposure
.map(|e| e.exposure())
.unwrap_or_else(|| ExposureSettings::default().exposure());
.unwrap_or_else(|| Exposure::default().exposure());

Some((
skybox.clone(),
Expand Down
18 changes: 13 additions & 5 deletions crates/bevy_pbr/src/light.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,12 @@ pub mod light_consts {
pub const CLEAR_SUNRISE: f32 = 400.;
/// The amount of light (lux) on a overcast day; typical TV studio lighting
pub const OVERCAST_DAY: f32 = 1000.;
/// The amount of light (lux) from ambient daylight (not direct sunlight).
pub const AMBIENT_DAYLIGHT: f32 = 10_000.;
/// The amount of light (lux) in full daylight (not direct sun).
pub const FULL_DAYLIGHT: f32 = 10_000.;
pub const FULL_DAYLIGHT: f32 = 20_000.;
/// The amount of light (lux) in direct sunlight.
pub const DIRECT_SUNLIGHT: f32 = 50_000.;
pub const DIRECT_SUNLIGHT: f32 = 100_000.;
}
}

Expand Down Expand Up @@ -113,7 +115,10 @@ impl Default for PointLight {
fn default() -> Self {
PointLight {
color: Color::rgb(1.0, 1.0, 1.0),
intensity: 2000.0, // Roughly a 20-watt LED bulb
// 1,000,000 lumens is a very large "cinema light" capable of registering brightly at Bevy's
// default "very overcast day" exposure level. For "indoor lighting" with a lower exposure,
// this would be way too bright.
intensity: 1_000_000.0,
range: 20.0,
radius: 0.0,
shadows_enabled: false,
Expand Down Expand Up @@ -181,7 +186,10 @@ impl Default for SpotLight {
// a quarter arc attenuating from the center
Self {
color: Color::rgb(1.0, 1.0, 1.0),
intensity: 2000.0, // Roughly a 20-watt LED bulb
// 1,000,000 lumens is a very large "cinema light" capable of registering brightly at Bevy's
// default "very overcast day" exposure level. For "indoor lighting" with a lower exposure,
// this would be way too bright.
intensity: 1_000_000.0,
range: 20.0,
radius: 0.0,
shadows_enabled: false,
Expand Down Expand Up @@ -262,7 +270,7 @@ impl Default for DirectionalLight {
fn default() -> Self {
DirectionalLight {
color: Color::rgb(1.0, 1.0, 1.0),
illuminance: light_consts::lux::OVERCAST_DAY,
illuminance: light_consts::lux::AMBIENT_DAYLIGHT,
shadows_enabled: false,
shadow_depth_bias: Self::DEFAULT_SHADOW_DEPTH_BIAS,
shadow_normal_bias: Self::DEFAULT_SHADOW_NORMAL_BIAS,
Expand Down
31 changes: 22 additions & 9 deletions crates/bevy_render/src/camera/camera.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,12 +90,12 @@ pub struct ComputedCameraValues {
///
/// <https://en.wikipedia.org/wiki/Exposure_(photography)>
#[derive(Component)]
pub struct ExposureSettings {
pub struct Exposure {
cart marked this conversation as resolved.
Show resolved Hide resolved
/// <https://en.wikipedia.org/wiki/Exposure_value#Tabulated_exposure_values>
pub ev100: f32,
}

impl ExposureSettings {
impl Exposure {
pub const SUNLIGHT: Self = Self {
ev100: Self::EV100_SUNLIGHT,
};
Expand All @@ -105,11 +105,24 @@ impl ExposureSettings {
pub const INDOOR: Self = Self {
ev100: Self::EV100_INDOOR,
};
/// This value was calibrated to match Blender's implicit/default exposure as closely as possible.
/// It also happens to be a reasonable default.
///
/// See <https://github.com/bevyengine/bevy/issues/11577> for details.
pub const BLENDER: Self = Self {
ev100: Self::EV100_BLENDER,
};

pub const EV100_SUNLIGHT: f32 = 15.0;
pub const EV100_OVERCAST: f32 = 12.0;
pub const EV100_INDOOR: f32 = 7.0;

/// This value was calibrated to match Blender's implicit/default exposure as closely as possible.
/// It also happens to be a reasonable default.
///
/// See <https://github.com/bevyengine/bevy/issues/11577> for details.
pub const EV100_BLENDER: f32 = 9.7;

pub fn from_physical_camera(physical_camera_parameters: PhysicalCameraParameters) -> Self {
Self {
ev100: physical_camera_parameters.ev100(),
Expand All @@ -124,14 +137,14 @@ impl ExposureSettings {
}
}

impl Default for ExposureSettings {
impl Default for Exposure {
fn default() -> Self {
Self::INDOOR
Self::BLENDER
}
}

/// Parameters based on physical camera characteristics for calculating
/// EV100 values for use with [`ExposureSettings`].
/// EV100 values for use with [`Exposure`].
#[derive(Clone, Copy)]
pub struct PhysicalCameraParameters {
/// <https://en.wikipedia.org/wiki/F-number>
Expand Down Expand Up @@ -798,7 +811,7 @@ pub fn extract_cameras(
&VisibleEntities,
&Frustum,
Option<&ColorGrading>,
Option<&ExposureSettings>,
Option<&Exposure>,
Option<&TemporalJitter>,
Option<&RenderLayers>,
Option<&Projection>,
Expand All @@ -815,7 +828,7 @@ pub fn extract_cameras(
visible_entities,
frustum,
color_grading,
exposure_settings,
exposure,
temporal_jitter,
render_layers,
projection,
Expand Down Expand Up @@ -858,9 +871,9 @@ pub fn extract_cameras(
clear_color: camera.clear_color.clone(),
// this will be set in sort_cameras
sorted_camera_index_for_target: 0,
exposure: exposure_settings
exposure: exposure
.map(|e| e.exposure())
.unwrap_or_else(|| ExposureSettings::default().exposure()),
.unwrap_or_else(|| Exposure::default().exposure()),
},
ExtractedView {
projection: camera.projection_matrix(),
Expand Down
4 changes: 2 additions & 2 deletions crates/bevy_render/src/view/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ pub use window::*;

use crate::{
camera::{
CameraMainTextureUsages, ClearColor, ClearColorConfig, ExposureSettings, ExtractedCamera,
CameraMainTextureUsages, ClearColor, ClearColorConfig, Exposure, ExtractedCamera,
ManualTextureViews, MipBias, TemporalJitter,
},
extract_resource::{ExtractResource, ExtractResourcePlugin},
Expand Down Expand Up @@ -434,7 +434,7 @@ pub fn prepare_view_uniforms(
world_position: extracted_view.transform.translation(),
exposure: extracted_camera
.map(|c| c.exposure)
.unwrap_or_else(|| ExposureSettings::default().exposure()),
.unwrap_or_else(|| Exposure::default().exposure()),
viewport,
frustum,
color_grading: extracted_view.color_grading,
Expand Down
7 changes: 3 additions & 4 deletions examples/3d/3d_gizmos.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,12 @@ fn setup(
..default()
});
// light
commands.spawn(DirectionalLightBundle {
directional_light: DirectionalLight {
illuminance: light_consts::lux::OVERCAST_DAY,
commands.spawn(PointLightBundle {
point_light: PointLight {
shadows_enabled: true,
..default()
},
transform: Transform::from_xyz(4.0, 8.0, 4.0).looking_at(Vec3::ZERO, Vec3::Y),
transform: Transform::from_xyz(4.0, 8.0, 4.0),
..default()
});

Expand Down
7 changes: 3 additions & 4 deletions examples/3d/3d_scene.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,12 @@ fn setup(
..default()
});
// light
commands.spawn(DirectionalLightBundle {
directional_light: DirectionalLight {
illuminance: light_consts::lux::OVERCAST_DAY,
commands.spawn(PointLightBundle {
point_light: PointLight {
shadows_enabled: true,
..default()
},
transform: Transform::from_xyz(4.0, 8.0, 4.0).looking_at(Vec3::ZERO, Vec3::Y),
transform: Transform::from_xyz(4.0, 8.0, 4.0),
..default()
});
// camera
Expand Down
9 changes: 5 additions & 4 deletions examples/3d/3d_shapes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,13 +64,14 @@ fn setup(
));
}

commands.spawn(DirectionalLightBundle {
directional_light: DirectionalLight {
illuminance: light_consts::lux::OVERCAST_DAY,
commands.spawn(PointLightBundle {
point_light: PointLight {
shadows_enabled: true,
intensity: 10_000_000.,
range: 100.0,
..default()
},
transform: Transform::from_xyz(8.0, 16.0, 8.0).looking_at(Vec3::ZERO, Vec3::Y),
transform: Transform::from_xyz(8.0, 16.0, 8.0),
..default()
});

Expand Down
1 change: 0 additions & 1 deletion examples/3d/3d_viewport_to_world.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@ fn setup(
// light
commands.spawn(DirectionalLightBundle {
transform: Transform::from_translation(Vec3::ONE).looking_at(Vec3::ZERO, Vec3::Y),
directional_light: DirectionalLight::default(),
..default()
});

Expand Down
2 changes: 1 addition & 1 deletion examples/3d/animated_material.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ fn setup(
EnvironmentMapLight {
diffuse_map: asset_server.load("environment_maps/pisa_diffuse_rgb9e5_zstd.ktx2"),
specular_map: asset_server.load("environment_maps/pisa_specular_rgb9e5_zstd.ktx2"),
intensity: 1_000.0,
intensity: 2_000.0,
},
));

Expand Down
2 changes: 1 addition & 1 deletion examples/3d/anti_aliasing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@ fn setup(
// Light
commands.spawn(DirectionalLightBundle {
directional_light: DirectionalLight {
illuminance: light_consts::lux::OVERCAST_DAY,
illuminance: light_consts::lux::FULL_DAYLIGHT,
shadows_enabled: true,
..default()
},
Expand Down
1 change: 0 additions & 1 deletion examples/3d/atmospheric_fog.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@ fn setup_terrain_scene(
commands.spawn(DirectionalLightBundle {
directional_light: DirectionalLight {
color: Color::rgb(0.98, 0.95, 0.82),
illuminance: light_consts::lux::OVERCAST_DAY,
shadows_enabled: true,
..default()
},
Expand Down
8 changes: 2 additions & 6 deletions examples/3d/blend_modes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,12 +167,8 @@ fn setup(
}

// Light
commands.spawn(DirectionalLightBundle {
directional_light: DirectionalLight {
illuminance: light_consts::lux::OVERCAST_DAY,
..default()
},
transform: Transform::from_xyz(4.0, 8.0, 4.0).looking_at(Vec3::ZERO, Vec3::Y),
commands.spawn(PointLightBundle {
transform: Transform::from_xyz(4.0, 8.0, 4.0),
..default()
});

Expand Down
6 changes: 3 additions & 3 deletions examples/3d/deferred_rendering.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ fn setup(
EnvironmentMapLight {
diffuse_map: asset_server.load("environment_maps/pisa_diffuse_rgb9e5_zstd.ktx2"),
specular_map: asset_server.load("environment_maps/pisa_specular_rgb9e5_zstd.ktx2"),
intensity: 250.0,
intensity: 2000.0,
},
DepthPrepass,
MotionVectorPrepass,
Expand All @@ -68,7 +68,7 @@ fn setup(

commands.spawn(DirectionalLightBundle {
directional_light: DirectionalLight {
illuminance: light_consts::lux::OVERCAST_DAY,
illuminance: 15_000.,
shadows_enabled: true,
..default()
},
Expand Down Expand Up @@ -140,7 +140,7 @@ fn setup(
// Light
commands.spawn(PointLightBundle {
point_light: PointLight {
intensity: 150.0,
intensity: 800.0,
radius: 0.125,
shadows_enabled: true,
color: sphere_color,
Expand Down
5 changes: 0 additions & 5 deletions examples/3d/fog.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
use bevy::{
pbr::{NotShadowCaster, NotShadowReceiver},
prelude::*,
render::camera::ExposureSettings,
};

fn main() {
Expand All @@ -43,9 +42,6 @@ fn setup_camera_fog(mut commands: Commands) {
},
..default()
},
// This is a dark scene,
// increasing the exposure makes it easier to see
ExposureSettings { ev100: 4.0 },
));
}

Expand Down Expand Up @@ -119,7 +115,6 @@ fn setup_pyramid_scene(
commands.spawn(PointLightBundle {
transform: Transform::from_xyz(0.0, 1.0, 0.0),
point_light: PointLight {
intensity: 4_000.,
shadows_enabled: true,
..default()
},
Expand Down
6 changes: 1 addition & 5 deletions examples/3d/generate_custom_mesh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,7 @@ fn setup(
});

// Light up the scene.
commands.spawn(DirectionalLightBundle {
directional_light: DirectionalLight {
illuminance: light_consts::lux::OVERCAST_DAY,
..default()
},
commands.spawn(PointLightBundle {
transform: camera_and_light_transform,
..default()
});
Expand Down
Loading
Loading