Exposure settings (adopted) (#11347)

Rebased and finished version of
https://github.com/bevyengine/bevy/pull/8407. Huge thanks to @GitGhillie
for adjusting all the examples, and the many other people who helped
write this PR (@superdump , @coreh , among others) :)

Fixes https://github.com/bevyengine/bevy/issues/8369

---

## Changelog
- Added a `brightness` control to `Skybox`.
- Added an `intensity` control to `EnvironmentMapLight`.
- Added `ExposureSettings` and `PhysicalCameraParameters` for
controlling exposure of 3D cameras.
- Removed the baked-in `DirectionalLight` exposure Bevy previously
hardcoded internally.

## Migration Guide
- If using a `Skybox` or `EnvironmentMapLight`, use the new `brightness`
and `intensity` controls to adjust their strength.
- All 3D scene will now have different apparent brightnesses due to Bevy
implementing proper exposure controls. You will have to adjust the
intensity of your lights and/or your camera exposure via the new
`ExposureSettings` component to compensate.

---------

Co-authored-by: Robert Swain <robert.swain@gmail.com>
Co-authored-by: GitGhillie <jillisnoordhoek@gmail.com>
Co-authored-by: Marco Buono <thecoreh@gmail.com>
Co-authored-by: vero <email@atlasdostal.com>
Co-authored-by: atlas dostal <rodol@rivalrebels.com>
This commit is contained in:
JMS55 2024-01-16 06:53:21 -08:00 committed by GitHub
parent 184f233a67
commit fcd7c0fc3d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
70 changed files with 436 additions and 131 deletions

View file

@ -76,13 +76,17 @@ impl ViewNode for MainOpaquePass3dNode {
}
// Draw the skybox using a fullscreen triangle
if let (Some(skybox_pipeline), Some(skybox_bind_group)) =
if let (Some(skybox_pipeline), Some(SkyboxBindGroup(skybox_bind_group))) =
(skybox_pipeline, skybox_bind_group)
{
let pipeline_cache = world.resource::<PipelineCache>();
if let Some(pipeline) = pipeline_cache.get_render_pipeline(skybox_pipeline.0) {
render_pass.set_render_pipeline(pipeline);
render_pass.set_bind_group(0, &skybox_bind_group.0, &[view_uniform_offset.offset]);
render_pass.set_bind_group(
0,
&skybox_bind_group.0,
&[view_uniform_offset.offset, skybox_bind_group.1],
);
render_pass.draw(0..3, 0..1);
}
}

View file

@ -2,21 +2,20 @@ use bevy_app::{App, Plugin};
use bevy_asset::{load_internal_asset, Handle};
use bevy_ecs::{
prelude::{Component, Entity},
query::With,
query::{QueryItem, With},
schedule::IntoSystemConfigs,
system::{Commands, Query, Res, ResMut, Resource},
};
use bevy_render::{
extract_component::{ExtractComponent, ExtractComponentPlugin},
camera::ExposureSettings,
extract_component::{
ComponentUniforms, DynamicUniformIndex, ExtractComponent, ExtractComponentPlugin,
UniformComponentPlugin,
},
render_asset::RenderAssets,
render_resource::{
binding_types::{sampler, texture_cube, uniform_buffer},
BindGroup, BindGroupEntries, BindGroupLayout, BindGroupLayoutEntries,
CachedRenderPipelineId, ColorTargetState, ColorWrites, CompareFunction, DepthBiasState,
DepthStencilState, FragmentState, MultisampleState, PipelineCache, PrimitiveState,
RenderPipelineDescriptor, SamplerBindingType, Shader, ShaderStages,
SpecializedRenderPipeline, SpecializedRenderPipelines, StencilFaceState, StencilState,
TextureFormat, TextureSampleType, VertexState,
*,
},
renderer::RenderDevice,
texture::{BevyDefault, Image},
@ -34,7 +33,10 @@ impl Plugin for SkyboxPlugin {
fn build(&self, app: &mut App) {
load_internal_asset!(app, SKYBOX_SHADER_HANDLE, "skybox.wgsl", Shader::from_wgsl);
app.add_plugins(ExtractComponentPlugin::<Skybox>::default());
app.add_plugins((
ExtractComponentPlugin::<Skybox>::default(),
UniformComponentPlugin::<SkyboxUniforms>::default(),
));
let Ok(render_app) = app.get_sub_app_mut(RenderApp) else {
return;
@ -68,8 +70,41 @@ impl Plugin for SkyboxPlugin {
/// To do so, use `EnvironmentMapLight` alongside this component.
///
/// See also <https://en.wikipedia.org/wiki/Skybox_(video_games)>.
#[derive(Component, ExtractComponent, Clone)]
pub struct Skybox(pub Handle<Image>);
#[derive(Component, Clone)]
pub struct Skybox {
pub image: Handle<Image>,
/// Scale factor applied to the skybox image.
/// After applying this multiplier to the image samples, the resulting values should
/// be in units of [cd/m^2](https://en.wikipedia.org/wiki/Candela_per_square_metre).
pub brightness: f32,
}
impl ExtractComponent for Skybox {
type Data = (&'static Self, Option<&'static ExposureSettings>);
type Filter = ();
type Out = (Self, SkyboxUniforms);
fn extract_component(
(skybox, exposure_settings): QueryItem<'_, Self::Data>,
) -> Option<Self::Out> {
let exposure = exposure_settings
.map(|e| e.exposure())
.unwrap_or_else(|| ExposureSettings::default().exposure());
Some((
skybox.clone(),
SkyboxUniforms {
brightness: skybox.brightness * exposure,
},
))
}
}
// TODO: Replace with a push constant once WebGPU gets support for that
#[derive(Component, ShaderType, Clone)]
pub struct SkyboxUniforms {
brightness: f32,
}
#[derive(Resource)]
struct SkyboxPipeline {
@ -88,6 +123,7 @@ impl SkyboxPipeline {
sampler(SamplerBindingType::Filtering),
uniform_buffer::<ViewUniform>(true)
.visibility(ShaderStages::VERTEX_FRAGMENT),
uniform_buffer::<SkyboxUniforms>(true),
),
),
),
@ -186,20 +222,23 @@ fn prepare_skybox_pipelines(
}
#[derive(Component)]
pub struct SkyboxBindGroup(pub BindGroup);
pub struct SkyboxBindGroup(pub (BindGroup, u32));
fn prepare_skybox_bind_groups(
mut commands: Commands,
pipeline: Res<SkyboxPipeline>,
view_uniforms: Res<ViewUniforms>,
skybox_uniforms: Res<ComponentUniforms<SkyboxUniforms>>,
images: Res<RenderAssets<Image>>,
render_device: Res<RenderDevice>,
views: Query<(Entity, &Skybox)>,
views: Query<(Entity, &Skybox, &DynamicUniformIndex<SkyboxUniforms>)>,
) {
for (entity, skybox) in &views {
if let (Some(skybox), Some(view_uniforms)) =
(images.get(&skybox.0), view_uniforms.uniforms.binding())
{
for (entity, skybox, skybox_uniform_index) in &views {
if let (Some(skybox), Some(view_uniforms), Some(skybox_uniforms)) = (
images.get(&skybox.image),
view_uniforms.uniforms.binding(),
skybox_uniforms.binding(),
) {
let bind_group = render_device.create_bind_group(
"skybox_bind_group",
&pipeline.bind_group_layout,
@ -207,10 +246,13 @@ fn prepare_skybox_bind_groups(
&skybox.texture_view,
&skybox.sampler,
view_uniforms,
skybox_uniforms,
)),
);
commands.entity(entity).insert(SkyboxBindGroup(bind_group));
commands
.entity(entity)
.insert(SkyboxBindGroup((bind_group, skybox_uniform_index.index())));
}
}
}

View file

@ -4,6 +4,7 @@
@group(0) @binding(0) var skybox: texture_cube<f32>;
@group(0) @binding(1) var skybox_sampler: sampler;
@group(0) @binding(2) var<uniform> view: View;
@group(0) @binding(3) var<uniform> brightness: f32;
fn coords_to_ray_direction(position: vec2<f32>, viewport: vec4<f32>) -> vec3<f32> {
// Using world positions of the fragment and camera to calculate a ray direction
@ -62,5 +63,5 @@ fn skybox_fragment(in: VertexOutput) -> @location(0) vec4<f32> {
let ray_direction = coords_to_ray_direction(in.position.xy, view.viewport);
// Cube maps are left-handed so we negate the z coordinate.
return textureSample(skybox, skybox_sampler, ray_direction * vec3(1.0, 1.0, -1.0));
return textureSample(skybox, skybox_sampler, ray_direction * vec3(1.0, 1.0, -1.0)) * brightness;
}

View file

@ -44,7 +44,7 @@ fn environment_map_light(
let kD = diffuse_color * Edss;
var out: EnvironmentMapLight;
out.diffuse = (FmsEms + kD) * irradiance;
out.specular = FssEss * radiance;
out.diffuse = (FmsEms + kD) * irradiance * bindings::lights.environment_map_intensity;
out.specular = FssEss * radiance * bindings::lights.environment_map_intensity;
return out;
}

View file

@ -51,6 +51,13 @@ impl Plugin for EnvironmentMapPlugin {
pub struct EnvironmentMapLight {
pub diffuse_map: Handle<Image>,
pub specular_map: Handle<Image>,
/// Scale factor applied to the diffuse and specular light generated by this component.
///
/// After applying this multiplier, the resulting values should
/// be in units of [cd/m^2](https://en.wikipedia.org/wiki/Candela_per_square_metre).
///
/// See also <https://google.github.io/filament/Filament.html#lighting/imagebasedlights/iblunit>.
pub intensity: f32,
}
impl EnvironmentMapLight {

View file

@ -557,7 +557,7 @@ fn calculate_cascade(
/// # use bevy_ecs::system::ResMut;
/// # use bevy_pbr::AmbientLight;
/// fn setup_ambient_light(mut ambient_light: ResMut<AmbientLight>) {
/// ambient_light.brightness = 0.3;
/// ambient_light.brightness = 20.0;
/// }
/// ```
#[derive(Resource, Clone, Debug, ExtractResource, Reflect)]
@ -572,7 +572,7 @@ impl Default for AmbientLight {
fn default() -> Self {
Self {
color: Color::rgb(1.0, 1.0, 1.0),
brightness: 0.05,
brightness: 8.0,
}
}
}

View file

@ -197,6 +197,7 @@ pub struct GpuLights {
// offset from spot light's light index to spot light's shadow map index
spot_light_shadowmap_offset: i32,
environment_map_smallest_specular_mip_level: u32,
environment_map_intensity: f32,
}
// NOTE: this must be kept in sync with the same constants in pbr.frag
@ -857,18 +858,6 @@ pub fn prepare_lights(
flags |= DirectionalLightFlags::SHADOWS_ENABLED;
}
// convert from illuminance (lux) to candelas
//
// exposure is hard coded at the moment but should be replaced
// by values coming from the camera
// see: https://google.github.io/filament/Filament.html#imagingpipeline/physicallybasedcamera/exposuresettings
const APERTURE: f32 = 4.0;
const SHUTTER_SPEED: f32 = 1.0 / 250.0;
const SENSITIVITY: f32 = 100.0;
let ev100 = f32::log2(APERTURE * APERTURE / SHUTTER_SPEED) - f32::log2(SENSITIVITY / 100.0);
let exposure = 1.0 / (f32::powf(2.0, ev100) * 1.2);
let intensity = light.illuminance * exposure;
let num_cascades = light
.cascade_shadow_config
.bounds
@ -877,9 +866,9 @@ pub fn prepare_lights(
gpu_directional_lights[index] = GpuDirectionalLight {
// Filled in later.
cascades: [GpuDirectionalCascade::default(); MAX_CASCADES_PER_LIGHT],
// premultiply color by intensity
// premultiply color by illuminance
// we don't use the alpha at all, so no reason to multiply only [0..3]
color: Vec4::from_slice(&light.color.as_linear_rgba_f32()) * intensity,
color: Vec4::from_slice(&light.color.as_linear_rgba_f32()) * light.illuminance,
// direction is negated to be ready for N.L
dir_to_light: light.transform.back(),
flags: flags.bits(),
@ -972,6 +961,9 @@ pub fn prepare_lights(
.and_then(|env_map| images.get(&env_map.specular_map))
.map(|specular_map| specular_map.mip_level_count - 1)
.unwrap_or(0),
environment_map_intensity: environment_map
.map(|env_map| env_map.intensity)
.unwrap_or(1.0),
};
// TODO: this should select lights based on relevance to the view instead of the first ones that show up in a query

View file

@ -58,6 +58,7 @@ struct Lights {
n_directional_lights: u32,
spot_light_shadowmap_offset: i32,
environment_map_smallest_specular_mip_level: u32,
environment_map_intensity: f32,
};
struct Fog {

View file

@ -386,7 +386,7 @@ fn apply_pbr_lighting(
// Total light
output_color = vec4<f32>(
transmitted_light + direct_light + indirect_light + emissive_light,
view_bindings::view.exposure * (transmitted_light + direct_light + indirect_light + emissive_light),
output_color.a
);
@ -423,7 +423,7 @@ fn apply_fog(fog_params: mesh_view_types::Fog, input_color: vec4<f32>, fragment_
0.0
),
fog_params.directional_light_exponent
) * light.color.rgb;
) * light.color.rgb * view_bindings::view.exposure;
}
}

View file

@ -42,6 +42,9 @@ fn specular_transmissive_light(world_position: vec4<f32>, frag_coord: vec3<f32>,
background_color = fetch_transmissive_background(offset_position, frag_coord, view_z, perceptual_roughness);
}
// Compensate for exposure, since the background color is coming from an already exposure-adjusted texture
background_color = vec4(background_color.rgb / view_bindings::view.exposure, background_color.a);
// Dot product of the refracted direction with the exit normal (Note: We assume the exit normal is the entry normal but inverted)
let MinusNdotT = dot(-N, T);

View file

@ -84,6 +84,73 @@ pub struct ComputedCameraValues {
old_viewport_size: Option<UVec2>,
}
/// How much energy a `Camera3d` absorbs from incoming light.
///
/// <https://en.wikipedia.org/wiki/Exposure_(photography)>
#[derive(Component)]
pub struct ExposureSettings {
/// <https://en.wikipedia.org/wiki/Exposure_value#Tabulated_exposure_values>
pub ev100: f32,
}
impl ExposureSettings {
pub const EV100_SUNLIGHT: f32 = 15.0;
pub const EV100_OVERCAST: f32 = 12.0;
pub const EV100_INDOOR: f32 = 7.0;
pub fn from_physical_camera(physical_camera_parameters: PhysicalCameraParameters) -> Self {
Self {
ev100: physical_camera_parameters.ev100(),
}
}
/// Converts EV100 values to exposure values.
/// <https://google.github.io/filament/Filament.md.html#imagingpipeline/physicallybasedcamera/exposure>
#[inline]
pub fn exposure(&self) -> f32 {
(-self.ev100).exp2() / 1.2
}
}
impl Default for ExposureSettings {
fn default() -> Self {
Self {
ev100: Self::EV100_INDOOR,
}
}
}
/// Parameters based on physical camera characteristics for calculating
/// EV100 values for use with [`ExposureSettings`].
#[derive(Clone, Copy)]
pub struct PhysicalCameraParameters {
/// <https://en.wikipedia.org/wiki/F-number>
pub aperture_f_stops: f32,
/// <https://en.wikipedia.org/wiki/Shutter_speed>
pub shutter_speed_s: f32,
/// <https://en.wikipedia.org/wiki/Film_speed>
pub sensitivity_iso: f32,
}
impl PhysicalCameraParameters {
/// Calculate the [EV100](https://en.wikipedia.org/wiki/Exposure_value).
pub fn ev100(&self) -> f32 {
(self.aperture_f_stops * self.aperture_f_stops * 100.0
/ (self.shutter_speed_s * self.sensitivity_iso))
.log2()
}
}
impl Default for PhysicalCameraParameters {
fn default() -> Self {
Self {
aperture_f_stops: 1.0,
shutter_speed_s: 1.0 / 125.0,
sensitivity_iso: 100.0,
}
}
}
/// The defining [`Component`] for camera entities,
/// storing information about how and what to render through this camera.
///
@ -695,6 +762,7 @@ pub struct ExtractedCamera {
pub msaa_writeback: bool,
pub clear_color: ClearColorConfig,
pub sorted_camera_index_for_target: usize,
pub exposure: f32,
}
pub fn extract_cameras(
@ -708,6 +776,7 @@ pub fn extract_cameras(
&VisibleEntities,
&Frustum,
Option<&ColorGrading>,
Option<&ExposureSettings>,
Option<&TemporalJitter>,
Option<&RenderLayers>,
Option<&Projection>,
@ -724,6 +793,7 @@ pub fn extract_cameras(
visible_entities,
frustum,
color_grading,
exposure_settings,
temporal_jitter,
render_layers,
projection,
@ -766,6 +836,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
.map(|e| e.exposure())
.unwrap_or_else(|| ExposureSettings::default().exposure()),
},
ExtractedView {
projection: camera.projection_matrix(),

View file

@ -7,7 +7,8 @@ pub use window::*;
use crate::{
camera::{
ClearColor, ClearColorConfig, ExtractedCamera, ManualTextureViews, MipBias, TemporalJitter,
ClearColor, ClearColorConfig, ExposureSettings, ExtractedCamera, ManualTextureViews,
MipBias, TemporalJitter,
},
extract_resource::{ExtractResource, ExtractResourcePlugin},
prelude::{Image, Shader},
@ -170,6 +171,7 @@ pub struct ViewUniform {
projection: Mat4,
inverse_projection: Mat4,
world_position: Vec3,
exposure: f32,
// viewport(x_origin, y_origin, width, height)
viewport: Vec4,
frustum: [Vec4; 6],
@ -368,6 +370,7 @@ pub fn prepare_view_uniforms(
mut view_uniforms: ResMut<ViewUniforms>,
views: Query<(
Entity,
Option<&ExtractedCamera>,
&ExtractedView,
Option<&Frustum>,
Option<&TemporalJitter>,
@ -384,9 +387,18 @@ pub fn prepare_view_uniforms(
else {
return;
};
for (entity, camera, frustum, temporal_jitter, mip_bias, maybe_layers) in &views {
let viewport = camera.viewport.as_vec4();
let unjittered_projection = camera.projection;
for (
entity,
extracted_camera,
extracted_view,
frustum,
temporal_jitter,
mip_bias,
maybe_layers,
) in &views
{
let viewport = extracted_view.viewport.as_vec4();
let unjittered_projection = extracted_view.projection;
let mut projection = unjittered_projection;
if let Some(temporal_jitter) = temporal_jitter {
@ -394,13 +406,13 @@ pub fn prepare_view_uniforms(
}
let inverse_projection = projection.inverse();
let view = camera.transform.compute_matrix();
let view = extracted_view.transform.compute_matrix();
let inverse_view = view.inverse();
let view_proj = if temporal_jitter.is_some() {
projection * inverse_view
} else {
camera
extracted_view
.view_projection
.unwrap_or_else(|| projection * inverse_view)
};
@ -419,10 +431,13 @@ pub fn prepare_view_uniforms(
inverse_view,
projection,
inverse_projection,
world_position: camera.transform.translation(),
world_position: extracted_view.transform.translation(),
exposure: extracted_camera
.map(|c| c.exposure)
.unwrap_or_else(|| ExposureSettings::default().exposure()),
viewport,
frustum,
color_grading: camera.color_grading,
color_grading: extracted_view.color_grading,
mip_bias: mip_bias.unwrap_or(&MipBias(0.0)).0,
render_layers: maybe_layers.copied().unwrap_or_default().bits(),
}),

View file

@ -16,6 +16,7 @@ struct View {
projection: mat4x4<f32>,
inverse_projection: mat4x4<f32>,
world_position: vec3<f32>,
exposure: f32,
// viewport(x_origin, y_origin, width, height)
viewport: vec4<f32>,
frustum: array<vec4<f32>, 6>,

View file

@ -37,7 +37,7 @@ fn setup(
// light
commands.spawn(PointLightBundle {
point_light: PointLight {
intensity: 1500.0,
intensity: 250000.0,
shadows_enabled: true,
..default()
},

View file

@ -32,7 +32,7 @@ fn setup(
// light
commands.spawn(PointLightBundle {
point_light: PointLight {
intensity: 1500.0,
intensity: 250_000.0,
shadows_enabled: true,
..default()
},

View file

@ -67,7 +67,7 @@ fn setup(
commands.spawn(PointLightBundle {
point_light: PointLight {
intensity: 9000.0,
intensity: 1500000.0,
range: 100.,
shadows_enabled: true,
..default()

View file

@ -61,6 +61,10 @@ fn setup(
// light
commands.spawn(DirectionalLightBundle {
transform: Transform::from_translation(Vec3::ONE).looking_at(Vec3::ZERO, Vec3::Y),
directional_light: DirectionalLight {
illuminance: 2000.0,
..default()
},
..default()
});

View file

@ -289,6 +289,7 @@ fn setup(
// Light
commands.spawn(DirectionalLightBundle {
directional_light: DirectionalLight {
illuminance: 3000.0,
shadows_enabled: true,
..default()
},
@ -325,6 +326,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: 150.0,
},
FogSettings {
color: Color::rgba_u8(43, 44, 47, 255),

View file

@ -61,6 +61,7 @@ fn setup_terrain_scene(
commands.spawn(DirectionalLightBundle {
directional_light: DirectionalLight {
color: Color::rgb(0.98, 0.95, 0.82),
illuminance: 3000.0,
shadows_enabled: true,
..default()
},

View file

@ -174,6 +174,10 @@ fn setup(
// Light
commands.spawn(PointLightBundle {
point_light: PointLight {
intensity: 150_000.0,
..default()
},
transform: Transform::from_xyz(4.0, 8.0, 4.0),
..default()
});

View file

@ -39,15 +39,15 @@ fn setup_scene(
));
let material_emissive1 = materials.add(StandardMaterial {
emissive: Color::rgb_linear(13.99, 5.32, 2.0), // 4. Put something bright in a dark environment to see the effect
emissive: Color::rgb_linear(2300.0, 900.0, 300.0), // 4. Put something bright in a dark environment to see the effect
..default()
});
let material_emissive2 = materials.add(StandardMaterial {
emissive: Color::rgb_linear(2.0, 13.99, 5.32),
emissive: Color::rgb_linear(300.0, 2300.0, 900.0),
..default()
});
let material_emissive3 = materials.add(StandardMaterial {
emissive: Color::rgb_linear(5.32, 2.0, 13.99),
emissive: Color::rgb_linear(900.0, 300.0, 2300.0),
..default()
});
let material_non_emissive = materials.add(StandardMaterial {

View file

@ -62,6 +62,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: 150.0,
},
DepthPrepass,
MotionVectorPrepass,
@ -71,6 +72,7 @@ fn setup(
commands.spawn(DirectionalLightBundle {
directional_light: DirectionalLight {
illuminance: 4000.0,
shadows_enabled: true,
..default()
},
@ -145,7 +147,7 @@ fn setup(
// Light
commands.spawn(PointLightBundle {
point_light: PointLight {
intensity: 1.0,
intensity: 150.0,
radius: 0.125,
shadows_enabled: true,
color: sphere_color,

View file

@ -128,7 +128,7 @@ fn setup_pyramid_scene(
commands.spawn(PointLightBundle {
transform: Transform::from_xyz(0.0, 1.0, 0.0),
point_light: PointLight {
intensity: 1500.,
intensity: 300_000.,
range: 100.,
shadows_enabled: true,
..default()

View file

@ -58,7 +58,7 @@ fn setup(
// Light up the scene.
commands.spawn(PointLightBundle {
point_light: PointLight {
intensity: 1000.0,
intensity: 100_000.0,
range: 100.0,
..default()
},

View file

@ -3,21 +3,34 @@
use std::f32::consts::PI;
use bevy::{pbr::CascadeShadowConfigBuilder, prelude::*};
use bevy::{
pbr::CascadeShadowConfigBuilder,
prelude::*,
render::camera::{ExposureSettings, PhysicalCameraParameters},
};
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.insert_resource(Parameters(PhysicalCameraParameters {
aperture_f_stops: 1.0,
shutter_speed_s: 1.0 / 15.0,
sensitivity_iso: 400.0,
}))
.add_systems(Startup, setup)
.add_systems(Update, (movement, animate_light_direction))
.add_systems(Update, (update_exposure, movement, animate_light_direction))
.run();
}
#[derive(Resource, Default, Deref, DerefMut)]
struct Parameters(PhysicalCameraParameters);
#[derive(Component)]
struct Movable;
/// set up a simple 3D scene
fn setup(
parameters: Res<Parameters>,
mut commands: Commands,
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<StandardMaterial>>,
@ -122,7 +135,7 @@ fn setup(
// transform: Transform::from_xyz(5.0, 8.0, 2.0),
transform: Transform::from_xyz(1.0, 2.0, 0.0),
point_light: PointLight {
intensity: 1600.0, // lumens - roughly a 100W non-halogen incandescent bulb
intensity: 4000.0, // lumens - roughly a 300W non-halogen incandescent bulb
color: Color::RED,
shadows_enabled: true,
..default()
@ -150,7 +163,7 @@ fn setup(
transform: Transform::from_xyz(-1.0, 2.0, 0.0)
.looking_at(Vec3::new(-1.0, 0.0, 0.0), Vec3::Z),
spot_light: SpotLight {
intensity: 1600.0, // lumens - roughly a 100W non-halogen incandescent bulb
intensity: 4000.0, // lumens - roughly a 300W non-halogen incandescent bulb
color: Color::GREEN,
shadows_enabled: true,
inner_angle: 0.6,
@ -182,7 +195,7 @@ fn setup(
// transform: Transform::from_xyz(5.0, 8.0, 2.0),
transform: Transform::from_xyz(0.0, 4.0, 0.0),
point_light: PointLight {
intensity: 1600.0, // lumens - roughly a 100W non-halogen incandescent bulb
intensity: 4000.0, // lumens - roughly a 300W non-halogen incandescent bulb
color: Color::BLUE,
shadows_enabled: true,
..default()
@ -207,6 +220,7 @@ fn setup(
// directional 'sun' light
commands.spawn(DirectionalLightBundle {
directional_light: DirectionalLight {
illuminance: 100.0,
shadows_enabled: true,
..default()
},
@ -227,21 +241,37 @@ fn setup(
..default()
});
// camera
commands.spawn(Camera3dBundle {
transform: Transform::from_xyz(-2.0, 2.5, 5.0).looking_at(Vec3::ZERO, Vec3::Y),
..default()
});
// example instructions
commands.spawn(
TextBundle::from_section(
"Use arrow keys to move objects",
TextStyle {
let style = TextStyle {
font_size: 20.0,
..default()
},
)
};
commands.spawn(
TextBundle::from_sections(vec![
TextSection::new(
format!("Aperture: f/{:.0}\n", parameters.aperture_f_stops),
style.clone(),
),
TextSection::new(
format!(
"Shutter speed: 1/{:.0}s\n",
1.0 / parameters.shutter_speed_s
),
style.clone(),
),
TextSection::new(
format!("Sensitivity: ISO {:.0}\n", parameters.sensitivity_iso),
style.clone(),
),
TextSection::new("\n\n", style.clone()),
TextSection::new("Controls\n", style.clone()),
TextSection::new("---------------\n", style.clone()),
TextSection::new("Arrow keys - Move objects\n", style.clone()),
TextSection::new("1/2 - Decrease/Increase aperture\n", style.clone()),
TextSection::new("3/4 - Decrease/Increase shutter speed\n", style.clone()),
TextSection::new("5/6 - Decrease/Increase sensitivity\n", style.clone()),
TextSection::new("R - Reset exposure", style),
])
.with_style(Style {
position_type: PositionType::Absolute,
top: Val::Px(12.0),
@ -249,6 +279,52 @@ fn setup(
..default()
}),
);
// camera
commands.spawn((
Camera3dBundle {
transform: Transform::from_xyz(-2.0, 2.5, 5.0).looking_at(Vec3::ZERO, Vec3::Y),
..default()
},
ExposureSettings::from_physical_camera(**parameters),
));
}
fn update_exposure(
key_input: Res<ButtonInput<KeyCode>>,
mut parameters: ResMut<Parameters>,
mut query: Query<&mut ExposureSettings>,
mut text: Query<&mut Text>,
) {
// TODO: Clamp values to a reasonable range
let mut text = text.single_mut();
if key_input.just_pressed(KeyCode::Digit2) {
parameters.aperture_f_stops *= 2.0;
} else if key_input.just_pressed(KeyCode::Digit1) {
parameters.aperture_f_stops *= 0.5;
}
if key_input.just_pressed(KeyCode::Digit4) {
parameters.shutter_speed_s *= 2.0;
} else if key_input.just_pressed(KeyCode::Digit3) {
parameters.shutter_speed_s *= 0.5;
}
if key_input.just_pressed(KeyCode::Digit6) {
parameters.sensitivity_iso += 100.0;
} else if key_input.just_pressed(KeyCode::Digit5) {
parameters.sensitivity_iso -= 100.0;
}
if key_input.just_pressed(KeyCode::KeyR) {
*parameters = Parameters::default();
}
text.sections[0].value = format!("Aperture: f/{:.0}\n", parameters.aperture_f_stops);
text.sections[1].value = format!(
"Shutter speed: 1/{:.0}s\n",
1.0 / parameters.shutter_speed_s
);
text.sections[2].value = format!("Sensitivity: ISO {:.0}\n", parameters.sensitivity_iso);
*query.single_mut() = ExposureSettings::from_physical_camera(**parameters);
}
fn animate_light_direction(

View file

@ -8,7 +8,7 @@ fn main() {
.add_plugins(DefaultPlugins)
.insert_resource(AmbientLight {
color: Color::WHITE,
brightness: 0.2,
brightness: 0.0,
})
.add_systems(Startup, setup)
.add_systems(Update, add_lightmaps_to_meshes)
@ -30,10 +30,21 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
fn add_lightmaps_to_meshes(
mut commands: Commands,
asset_server: Res<AssetServer>,
meshes: Query<(Entity, &Name), (With<Handle<Mesh>>, Without<Lightmap>)>,
mut materials: ResMut<Assets<StandardMaterial>>,
meshes: Query<
(Entity, &Name, &Handle<StandardMaterial>),
(With<Handle<Mesh>>, Without<Lightmap>),
>,
) {
for (entity, name) in meshes.iter() {
let exposure = 250.0;
for (entity, name, material) in meshes.iter() {
if &**name == "Light" {
materials.get_mut(material).unwrap().emissive = Color::WHITE * exposure;
continue;
}
if &**name == "large_box" {
materials.get_mut(material).unwrap().lightmap_exposure = exposure;
commands.entity(entity).insert(Lightmap {
image: asset_server.load("lightmaps/CornellBox-Large.zstd.ktx2"),
..default()
@ -42,6 +53,7 @@ fn add_lightmaps_to_meshes(
}
if &**name == "small_box" {
materials.get_mut(material).unwrap().lightmap_exposure = exposure;
commands.entity(entity).insert(Lightmap {
image: asset_server.load("lightmaps/CornellBox-Small.zstd.ktx2"),
..default()
@ -50,6 +62,7 @@ fn add_lightmaps_to_meshes(
}
if name.starts_with("cornell_box") {
materials.get_mut(material).unwrap().lightmap_exposure = exposure;
commands.entity(entity).insert(Lightmap {
image: asset_server.load("lightmaps/CornellBox-Box.zstd.ktx2"),
..default()

View file

@ -25,11 +25,13 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
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: 150.0,
},
));
commands.spawn(DirectionalLightBundle {
directional_light: DirectionalLight {
illuminance: 2000.0,
shadows_enabled: true,
..default()
},

View file

@ -61,6 +61,10 @@ fn setup(
// light
commands.spawn(PointLightBundle {
transform: Transform::from_xyz(3.0, 8.0, 5.0),
point_light: PointLight {
intensity: 150_000.0,
..default()
},
..default()
});
}

View file

@ -224,7 +224,7 @@ fn setup(
.spawn(PointLightBundle {
transform: Transform::from_xyz(1.8, 0.7, -1.1),
point_light: PointLight {
intensity: 226.0,
intensity: 50_000.0,
shadows_enabled: true,
..default()
},

View file

@ -57,6 +57,10 @@ fn setup(
// light
commands.spawn(PointLightBundle {
transform: Transform::from_xyz(4.0, 5.0, -4.0),
point_light: PointLight {
intensity: 150_000.0,
..default()
},
..default()
});
// camera

View file

@ -61,7 +61,7 @@ fn setup(
commands.spawn(PointLightBundle {
transform: Transform::from_xyz(50.0, 50.0, 50.0),
point_light: PointLight {
intensity: 600000.,
intensity: 100_000_000.,
range: 100.,
..default()
},
@ -138,6 +138,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: 150.0,
},
));
}

View file

@ -92,6 +92,10 @@ fn setup(
commands.spawn((
PointLightBundle {
transform: Transform::from_translation(Vec3::new(0.0, 0.0, 10.0)),
point_light: PointLight {
intensity: 150_000.0,
..default()
},
..default()
},
RenderLayers::all(),

View file

@ -74,7 +74,7 @@ fn setup(
});
builder.spawn(DirectionalLightBundle {
directional_light: DirectionalLight {
illuminance: 100000.0,
illuminance: 1500.0,
shadow_depth_bias: 0.0,
shadow_normal_bias: 0.0,
shadows_enabled: true,

View file

@ -98,7 +98,7 @@ fn setup(
commands.spawn(DirectionalLightBundle {
directional_light: DirectionalLight {
illuminance: 100000.0,
illuminance: 1500.0,
shadows_enabled: true,
..default()
},
@ -134,7 +134,7 @@ fn toggle_light(
for mut light in &mut point_lights {
light.intensity = if light.intensity == 0.0 {
println!("Using PointLight");
100000000.0
500_000.0
} else {
0.0
};
@ -142,7 +142,7 @@ fn toggle_light(
for mut light in &mut directional_lights {
light.illuminance = if light.illuminance == 0.0 {
println!("Using DirectionalLight");
100000.0
1500.0
} else {
0.0
};

View file

@ -78,7 +78,10 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
..default()
},
CameraController::default(),
Skybox(skybox_handle.clone()),
Skybox {
image: skybox_handle.clone(),
brightness: 150.0,
},
));
// ambient light
@ -157,7 +160,7 @@ fn asset_loaded(
}
for mut skybox in &mut skyboxes {
skybox.0 = cubemap.image_handle.clone();
skybox.image = cubemap.image_handle.clone();
}
cubemap.is_loaded = true;

View file

@ -16,7 +16,7 @@ fn setup(
) {
// camera
commands.spawn(Camera3dBundle {
transform: Transform::from_xyz(1.0, 2.5, 5.0).looking_at(Vec3::ZERO, Vec3::Y),
transform: Transform::from_xyz(0.2, 1.5, 2.5).looking_at(Vec3::ZERO, Vec3::Y),
..default()
});
@ -32,8 +32,8 @@ fn setup(
});
const COUNT: usize = 6;
let position_range = -4.0..4.0;
let radius_range = 0.0..0.8;
let position_range = -2.0..2.0;
let radius_range = 0.0..0.4;
let pos_len = position_range.end - position_range.start;
let radius_len = radius_range.end - radius_range.start;
let mesh = meshes.add(shape::UVSphere {
@ -55,14 +55,14 @@ fn setup(
unlit: true,
..default()
}),
transform: Transform::from_xyz(position_range.start + percent * pos_len, 0.6, 0.0)
transform: Transform::from_xyz(position_range.start + percent * pos_len, 0.3, 0.0)
.with_scale(Vec3::splat(radius)),
..default()
})
.with_children(|children| {
children.spawn(PointLightBundle {
point_light: PointLight {
intensity: 1500.0,
intensity: 100_000.0,
radius,
color: Color::rgb(0.2, 0.2, 1.0),
..default()

View file

@ -37,6 +37,7 @@ fn setup(
commands.spawn(DirectionalLightBundle {
transform: Transform::from_rotation(Quat::from_euler(EulerRot::ZYX, 0.0, 1.0, -PI / 4.)),
directional_light: DirectionalLight {
illuminance: 1500.0,
shadows_enabled: true,
..default()
},

View file

@ -10,7 +10,7 @@ use rand::{rngs::StdRng, Rng, SeedableRng};
fn main() {
App::new()
.insert_resource(AmbientLight {
brightness: 0.02,
brightness: 4.0,
..default()
})
.add_plugins((
@ -69,12 +69,12 @@ fn setup(
});
let red_emissive = materials.add(StandardMaterial {
base_color: Color::RED,
emissive: Color::rgba_linear(1.0, 0.0, 0.0, 0.0),
emissive: Color::rgba_linear(100.0, 0.0, 0.0, 0.0),
..default()
});
let maroon_emissive = materials.add(StandardMaterial {
base_color: Color::MAROON,
emissive: Color::rgba_linear(0.369, 0.0, 0.0, 0.0),
emissive: Color::rgba_linear(50.0, 0.0, 0.0, 0.0),
..default()
});
for x in 0..4 {
@ -87,7 +87,7 @@ fn setup(
transform: Transform::from_xyz(1.0 + x, 2.0, z)
.looking_at(Vec3::new(1.0 + x, 0.0, z), Vec3::X),
spot_light: SpotLight {
intensity: 200.0, // lumens
intensity: 100_000.0, // lumens
color: Color::WHITE,
shadows_enabled: true,
inner_angle: PI / 4.0 * 0.85,

View file

@ -14,7 +14,7 @@ use std::f32::consts::PI;
fn main() {
App::new()
.insert_resource(AmbientLight {
brightness: 5.0,
brightness: 750.0,
..default()
})
.add_plugins((DefaultPlugins, TemporalAntiAliasPlugin))
@ -85,6 +85,7 @@ fn setup(
commands.spawn(DirectionalLightBundle {
directional_light: DirectionalLight {
illuminance: 3000.0,
shadows_enabled: true,
..default()
},

View file

@ -76,6 +76,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: 150.0,
},
));
@ -194,7 +195,7 @@ fn setup_basic_scene(
DirectionalLightBundle {
directional_light: DirectionalLight {
shadows_enabled: true,
illuminance: 50000.0,
illuminance: 3000.0,
..default()
},
transform: Transform::from_rotation(Quat::from_euler(

View file

@ -153,7 +153,7 @@ fn setup(
PbrBundle {
mesh: icosphere_mesh.clone(),
material: materials.add(StandardMaterial {
emissive: Color::ANTIQUE_WHITE * 20.0 + Color::ORANGE_RED * 4.0,
emissive: Color::ANTIQUE_WHITE * 80.0 + Color::ORANGE_RED * 16.0,
diffuse_transmission: 1.0,
..default()
}),
@ -325,7 +325,7 @@ fn setup(
transform: Transform::from_xyz(-1.0, 1.7, 0.0),
point_light: PointLight {
color: Color::ANTIQUE_WHITE * 0.8 + Color::ORANGE_RED * 0.2,
intensity: 1600.0,
intensity: 60_000.0,
radius: 0.2,
range: 5.0,
shadows_enabled: true,
@ -345,7 +345,6 @@ fn setup(
},
transform: Transform::from_xyz(1.0, 1.8, 7.0).looking_at(Vec3::ZERO, Vec3::Y),
color_grading: ColorGrading {
exposure: -2.0,
post_saturation: 1.2,
..default()
},
@ -355,6 +354,7 @@ fn setup(
#[cfg(not(all(feature = "webgl2", target_arch = "wasm32")))]
TemporalAntiAliasBundle::default(),
EnvironmentMapLight {
intensity: 25.0,
diffuse_map: asset_server.load("environment_maps/pisa_diffuse_rgb9e5_zstd.ktx2"),
specular_map: asset_server.load("environment_maps/pisa_specular_rgb9e5_zstd.ktx2"),
},
@ -648,7 +648,7 @@ fn flicker_system(
let c = (s * 7.0).cos() * 0.0125 + (s * 2.0).cos() * 0.025;
let (mut light, mut light_transform) = light.single_mut();
let mut flame_transform = flame.single_mut();
light.intensity = 1600.0 + 3000.0 * (a + b + c);
light.intensity = 60_000.0 + 3000.0 * (a + b + c);
flame_transform.translation = Vec3::new(-1.0, 1.23, 0.0);
flame_transform.look_at(Vec3::new(-1.0 - c, 1.7 - b, 0.0 - a), Vec3::X);
flame_transform.rotate(Quat::from_euler(EulerRot::XYZ, 0.0, 0.0, PI / 2.0));

View file

@ -91,7 +91,7 @@ fn setup(
// light
commands.spawn(PointLightBundle {
point_light: PointLight {
intensity: 1500.0,
intensity: 1_000_000.0,
shadows_enabled: true,
..default()
},

View file

@ -31,7 +31,7 @@ fn setup(
// light
commands.spawn(PointLightBundle {
point_light: PointLight {
intensity: 1500.0,
intensity: 500_000.0,
shadows_enabled: true,
..default()
},

View file

@ -19,6 +19,7 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
commands.spawn(DirectionalLightBundle {
transform: Transform::from_xyz(4.0, 25.0, 8.0).looking_at(Vec3::ZERO, Vec3::Y),
directional_light: DirectionalLight {
illuminance: 2000.0,
shadows_enabled: true,
..default()
},
@ -33,6 +34,7 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
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: 150.0,
},
));

View file

@ -45,7 +45,7 @@ fn setup(
// light
commands.spawn(PointLightBundle {
point_light: PointLight {
intensity: 1500.0,
intensity: 500_000.0,
shadows_enabled: true,
..default()
},

View file

@ -95,6 +95,10 @@ fn setup(
// light
commands.spawn(PointLightBundle {
transform: Transform::from_xyz(4.0, 8.0, 4.0),
point_light: PointLight {
intensity: 150_000.0,
..default()
},
..default()
});

View file

@ -10,7 +10,7 @@ fn main() {
.add_plugins(DefaultPlugins)
.insert_resource(AmbientLight {
color: Color::WHITE,
brightness: 1.0,
brightness: 150.0,
})
.add_systems(Startup, setup)
.add_systems(
@ -54,6 +54,7 @@ fn setup(
commands.spawn(DirectionalLightBundle {
transform: Transform::from_rotation(Quat::from_euler(EulerRot::ZYX, 0.0, 1.0, -PI / 4.)),
directional_light: DirectionalLight {
illuminance: 2000.0,
shadows_enabled: true,
..default()
},

View file

@ -9,7 +9,7 @@ fn main() {
.add_plugins(DefaultPlugins)
.insert_resource(AmbientLight {
color: Color::WHITE,
brightness: 1.0,
brightness: 150.0,
})
.add_systems(Startup, setup)
.run();

View file

@ -49,7 +49,7 @@ fn setup(
// Some light to see something
commands.spawn(PointLightBundle {
point_light: PointLight {
intensity: 9000.,
intensity: 1_500_000.,
range: 100.,
shadows_enabled: true,
..default()

View file

@ -20,7 +20,7 @@ fn main() {
App::new()
.add_plugins(DefaultPlugins)
.insert_resource(AmbientLight {
brightness: 1.0,
brightness: 150.0,
..default()
})
.add_systems(Startup, setup)

View file

@ -9,7 +9,7 @@ fn main() {
App::new()
.add_plugins(DefaultPlugins)
.insert_resource(AmbientLight {
brightness: 1.0,
brightness: 150.0,
..default()
})
.add_systems(Startup, setup)

View file

@ -20,7 +20,7 @@ fn main() {
..default()
}))
.insert_resource(AmbientLight {
brightness: 1.0,
brightness: 150.0,
..default()
})
.add_systems(Startup, setup)
@ -46,7 +46,7 @@ fn setup(asset_server: Res<AssetServer>, mut commands: Commands) {
commands.spawn(DirectionalLightBundle {
directional_light: DirectionalLight {
color: Color::WHITE,
illuminance: 19350.0,
illuminance: 1000.0,
..default()
},
transform: Transform::from_rotation(Quat::from_rotation_z(PI / 2.0)),

View file

@ -61,7 +61,7 @@ fn setup(
// light
commands.spawn(PointLightBundle {
point_light: PointLight {
intensity: 1500.0,
intensity: 1_000_000.0,
shadows_enabled: true,
..default()
},

View file

@ -112,7 +112,7 @@ fn generate_bodies(
),
material: materials.add(StandardMaterial {
base_color: Color::ORANGE_RED,
emissive: Color::ORANGE_RED * 2.,
emissive: (Color::ORANGE_RED * 18.),
..default()
}),
..default()
@ -126,7 +126,7 @@ fn generate_bodies(
p.spawn(PointLightBundle {
point_light: PointLight {
color: Color::WHITE,
intensity: 400.0,
intensity: 100_000.0,
range: 100.0,
radius: star_radius,
..default()

View file

@ -115,7 +115,7 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>, mut game: ResMu
commands.spawn(PointLightBundle {
transform: Transform::from_xyz(4.0, 10.0, 4.0),
point_light: PointLight {
intensity: 3000.0,
intensity: 500_000.0,
shadows_enabled: true,
range: 30.0,
..default()
@ -344,7 +344,7 @@ fn spawn_bonus(
children.spawn(PointLightBundle {
point_light: PointLight {
color: Color::rgb(1.0, 1.0, 0.0),
intensity: 1000.0,
intensity: 100_000.0,
range: 10.0,
..default()
},

View file

@ -90,7 +90,7 @@ fn setup_scene(
commands.spawn(PointLightBundle {
transform: Transform::from_xyz(4.0, 8.0, 4.0),
point_light: PointLight {
intensity: 5000.0,
intensity: 1_000_000.0,
// Shadows makes some Android devices segfault, this is under investigation
// https://github.com/bevyengine/bevy/issues/8214
#[cfg(not(target_os = "android"))]

View file

@ -34,7 +34,7 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
// light
commands.spawn(PointLightBundle {
point_light: PointLight {
intensity: 3000.0,
intensity: 150_000.0,
..Default::default()
},
transform: Transform::from_xyz(-3.0, 2.0, -1.0),
@ -42,7 +42,7 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
});
commands.spawn(PointLightBundle {
point_light: PointLight {
intensity: 3000.0,
intensity: 150_000.0,
..Default::default()
},
transform: Transform::from_xyz(3.0, 2.0, 1.0),

View file

@ -50,7 +50,16 @@ fn setup(
});
// light
commands.spawn((PointLightBundle::default(), Rotate));
commands.spawn((
PointLightBundle {
point_light: PointLight {
intensity: 150_000.0,
..default()
},
..default()
},
Rotate,
));
// camera
commands.spawn(Camera3dBundle {

View file

@ -331,6 +331,10 @@ fn setup(
));
// light
commands.spawn(PointLightBundle {
point_light: PointLight {
intensity: 150_000.0,
..default()
},
transform: Transform::from_translation(Vec3::new(0.0, 0.0, 10.0)),
..default()
});

View file

@ -30,6 +30,10 @@ fn setup(
..default()
});
commands.spawn(PointLightBundle {
point_light: PointLight {
intensity: 150_000.0,
..default()
},
transform: Transform::from_xyz(4.0, 8.0, 4.0),
..default()
});

View file

@ -125,7 +125,7 @@ fn setup(
// light
commands.spawn(PointLightBundle {
point_light: PointLight {
intensity: 1500.0,
intensity: 300_000.0,
shadows_enabled: true,
..default()
},

View file

@ -15,7 +15,7 @@ use bevy::{
#[derive(FromArgs, Resource)]
/// `many_foxes` stress test
struct Args {
/// wether all foxes run in sync.
/// whether all foxes run in sync.
#[argh(switch)]
sync: bool,
@ -58,7 +58,7 @@ fn main() {
})
.insert_resource(AmbientLight {
color: Color::WHITE,
brightness: 1.0,
brightness: 100.0,
})
.add_systems(Startup, setup)
.add_systems(
@ -194,6 +194,7 @@ fn setup(
commands.spawn(DirectionalLightBundle {
transform: Transform::from_rotation(Quat::from_euler(EulerRot::ZYX, 0.0, 1.0, -PI / 4.)),
directional_light: DirectionalLight {
illuminance: 3000.0,
shadows_enabled: true,
..default()
},

View file

@ -28,11 +28,7 @@ use scene_viewer_plugin::{SceneHandle, SceneViewerPlugin};
fn main() {
let mut app = App::new();
app.insert_resource(AmbientLight {
color: Color::WHITE,
brightness: 1.0 / 5.0f32,
})
.add_plugins((
app.add_plugins((
DefaultPlugins
.set(WindowPlugin {
primary_window: Some(Window {
@ -144,6 +140,7 @@ fn setup_scene_after_load(
.load("assets/environment_maps/pisa_diffuse_rgb9e5_zstd.ktx2"),
specular_map: asset_server
.load("assets/environment_maps/pisa_specular_rgb9e5_zstd.ktx2"),
intensity: 150.0,
},
camera_controller,
));
@ -153,6 +150,7 @@ fn setup_scene_after_load(
info!("Spawning a directional light");
commands.spawn(DirectionalLightBundle {
directional_light: DirectionalLight {
illuminance: 3000.0,
shadows_enabled: false,
..default()
},

View file

@ -42,6 +42,10 @@ fn setup(
// Add a light source so we can see clearly.
commands.spawn(PointLightBundle {
point_light: PointLight {
intensity: 150_000.0,
..default()
},
transform: Transform::from_translation(Vec3::ONE * 3.0),
..default()
});

View file

@ -58,6 +58,10 @@ fn setup(
// Add a light source for better 3d visibility.
commands.spawn(PointLightBundle {
point_light: PointLight {
intensity: 150_000.0,
..default()
},
transform: Transform::from_translation(Vec3::ONE * 3.0),
..default()
});

View file

@ -93,6 +93,10 @@ fn setup(
// Add a light source for better 3d visibility.
commands.spawn(PointLightBundle {
point_light: PointLight {
intensity: 150_000.0,
..default()
},
transform: Transform::from_translation(Vec3::ONE * 3.0),
..default()
});

View file

@ -56,6 +56,10 @@ fn setup(
// Add a light source for better 3d visibility.
commands.spawn(PointLightBundle {
point_light: PointLight {
intensity: 150_000.0,
..default()
},
transform: Transform::from_translation(Vec3::ONE * 3.0),
..default()
});

View file

@ -158,7 +158,7 @@ pub(crate) mod test_setup {
));
commands.spawn(PointLightBundle {
point_light: PointLight {
intensity: 1500.0,
intensity: 1_000_000.0,
shadows_enabled: true,
..default()
},

View file

@ -19,6 +19,10 @@ fn setup_scene(mut commands: Commands, asset_server: Res<AssetServer>) {
});
// light
commands.spawn(PointLightBundle {
point_light: PointLight {
intensity: 150_000.0,
..default()
},
transform: Transform::from_xyz(4.0, 5.0, 4.0),
..default()
});

View file

@ -49,7 +49,7 @@ fn setup(
// light
commands.spawn(PointLightBundle {
point_light: PointLight {
intensity: 1500.0,
intensity: 500_000.0,
shadows_enabled: true,
..default()
},