Replace Ambient Lights with Environment Map Lights (#17482)

# Objective

Transparently uses simple `EnvironmentMapLight`s to mimic
`AmbientLight`s. Implements the first part of #17468, but I can
implement hemispherical lights in this PR too if needed.

## Solution

- A function `EnvironmentMapLight::solid_color(&mut Assets<Image>,
Color)` is provided to make an environment light with a solid color.
- A new system is added to `SimulationLightSystems` that maps
`AmbientLight`s on views or the world to a corresponding
`EnvironmentMapLight`.

I have never worked with (or on) Bevy before, so nitpicky comments on
how I did things are appreciated :).

## Testing

Testing was done on a modified version of the `3d/lighting` example,
where I removed all lights except the ambient light. I have not included
the example, but can if required.

## Migration
`bevy_pbr::AmbientLight` has been deprecated, so all usages of it should
be replaced by a `bevy_pbr::EnvironmentMapLight` created with
`EnvironmentMapLight::solid_color` placed on the camera. There is no
alternative to ambient lights as resources.
This commit is contained in:
Shaye Garg 2025-03-04 01:40:53 -06:00 committed by GitHub
parent 0a841ba9c1
commit 0b5302d96a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
35 changed files with 348 additions and 212 deletions

View File

@ -71,10 +71,16 @@ pub use volumetric_fog::{FogVolume, VolumetricFog, VolumetricFogPlugin, Volumetr
/// ///
/// This includes the most common types in this crate, re-exported for your convenience. /// This includes the most common types in this crate, re-exported for your convenience.
pub mod prelude { pub mod prelude {
#[expect(
deprecated,
reason = "AmbientLight has been replaced by EnvironmentMapLight"
)]
#[doc(hidden)]
pub use crate::light::AmbientLight;
#[doc(hidden)] #[doc(hidden)]
pub use crate::{ pub use crate::{
fog::{DistanceFog, FogFalloff}, fog::{DistanceFog, FogFalloff},
light::{light_consts, AmbientLight, DirectionalLight, PointLight, SpotLight}, light::{light_consts, DirectionalLight, PointLight, SpotLight},
light_probe::{environment_map::EnvironmentMapLight, LightProbe}, light_probe::{environment_map::EnvironmentMapLight, LightProbe},
material::{Material, MaterialPlugin}, material::{Material, MaterialPlugin},
mesh_material::MeshMaterial3d, mesh_material::MeshMaterial3d,
@ -165,7 +171,6 @@ pub const PBR_PREPASS_SHADER_HANDLE: Handle<Shader> =
weak_handle!("9afeaeab-7c45-43ce-b322-4b97799eaeb9"); weak_handle!("9afeaeab-7c45-43ce-b322-4b97799eaeb9");
pub const PBR_FUNCTIONS_HANDLE: Handle<Shader> = pub const PBR_FUNCTIONS_HANDLE: Handle<Shader> =
weak_handle!("815b8618-f557-4a96-91a5-a2fb7e249fb0"); weak_handle!("815b8618-f557-4a96-91a5-a2fb7e249fb0");
pub const PBR_AMBIENT_HANDLE: Handle<Shader> = weak_handle!("4a90b95b-112a-4a10-9145-7590d6f14260");
pub const PARALLAX_MAPPING_SHADER_HANDLE: Handle<Shader> = pub const PARALLAX_MAPPING_SHADER_HANDLE: Handle<Shader> =
weak_handle!("6cf57d9f-222a-429a-bba4-55ba9586e1d4"); weak_handle!("6cf57d9f-222a-429a-bba4-55ba9586e1d4");
pub const VIEW_TRANSFORMATIONS_SHADER_HANDLE: Handle<Shader> = pub const VIEW_TRANSFORMATIONS_SHADER_HANDLE: Handle<Shader> =
@ -280,12 +285,6 @@ impl Plugin for PbrPlugin {
"render/rgb9e5.wgsl", "render/rgb9e5.wgsl",
Shader::from_wgsl Shader::from_wgsl
); );
load_internal_asset!(
app,
PBR_AMBIENT_HANDLE,
"render/pbr_ambient.wgsl",
Shader::from_wgsl
);
load_internal_asset!( load_internal_asset!(
app, app,
PBR_FRAGMENT_HANDLE, PBR_FRAGMENT_HANDLE,
@ -325,6 +324,10 @@ impl Plugin for PbrPlugin {
Shader::from_wgsl Shader::from_wgsl
); );
#[expect(
deprecated,
reason = "AmbientLight has been replaced by EnvironmentMapLight"
)]
app.register_asset_reflect::<StandardMaterial>() app.register_asset_reflect::<StandardMaterial>()
.register_type::<AmbientLight>() .register_type::<AmbientLight>()
.register_type::<CascadeShadowConfig>() .register_type::<CascadeShadowConfig>()
@ -401,6 +404,9 @@ impl Plugin for PbrPlugin {
.add_systems( .add_systems(
PostUpdate, PostUpdate,
( (
map_ambient_lights
.in_set(SimulationLightSystems::MapAmbientLights)
.after(CameraUpdateSystem),
add_clusters add_clusters
.in_set(SimulationLightSystems::AddClusters) .in_set(SimulationLightSystems::AddClusters)
.after(CameraUpdateSystem), .after(CameraUpdateSystem),

View File

@ -1,3 +1,8 @@
#![deprecated(
since = "0.16.0",
note = "Use `EnvironmentMapLight::solid_color` instead"
)]
use super::*; use super::*;
/// An ambient light, which lights the entire scene equally. /// An ambient light, which lights the entire scene equally.

View File

@ -20,9 +20,13 @@ use bevy_render::{
use bevy_transform::components::{GlobalTransform, Transform}; use bevy_transform::components::{GlobalTransform, Transform};
use bevy_utils::Parallel; use bevy_utils::Parallel;
use crate::*; use crate::{prelude::EnvironmentMapLight, *};
mod ambient_light; mod ambient_light;
#[expect(
deprecated,
reason = "AmbientLight has been replaced by EnvironmentMapLight"
)]
pub use ambient_light::AmbientLight; pub use ambient_light::AmbientLight;
mod point_light; mod point_light;
@ -509,6 +513,7 @@ pub struct LightVisibilityClass;
/// System sets used to run light-related systems. /// System sets used to run light-related systems.
#[derive(Debug, Hash, PartialEq, Eq, Clone, SystemSet)] #[derive(Debug, Hash, PartialEq, Eq, Clone, SystemSet)]
pub enum SimulationLightSystems { pub enum SimulationLightSystems {
MapAmbientLights,
AddClusters, AddClusters,
AssignLightsToClusters, AssignLightsToClusters,
/// System order ambiguities between systems in this set are ignored: /// System order ambiguities between systems in this set are ignored:
@ -522,6 +527,58 @@ pub enum SimulationLightSystems {
CheckLightVisibility, CheckLightVisibility,
} }
#[derive(Component)]
pub struct EnvironmentMapLightFromAmbientLight;
#[expect(
deprecated,
reason = "AmbientLight has been replaced by EnvironmentMapLight"
)]
pub fn map_ambient_lights(
mut commands: Commands,
mut image_assets: ResMut<Assets<Image>>,
ambient_light: Res<AmbientLight>,
new_views: Query<
(Entity, Option<Ref<AmbientLight>>),
(
With<Camera>,
Without<EnvironmentMapLight>,
Without<EnvironmentMapLightFromAmbientLight>,
),
>,
mut managed_views: Query<
(&mut EnvironmentMapLight, Option<Ref<AmbientLight>>),
With<EnvironmentMapLightFromAmbientLight>,
>,
) {
let ambient_light = ambient_light.into();
for (entity, ambient_override) in new_views.iter() {
let ambient = ambient_override.as_ref().unwrap_or(&ambient_light);
let ambient_required = ambient.brightness > 0.0 && ambient.color != Color::BLACK;
if ambient_required && ambient.is_changed() {
commands
.entity(entity)
.insert(EnvironmentMapLight {
intensity: ambient.brightness,
affects_lightmapped_mesh_diffuse: ambient.affects_lightmapped_meshes,
..EnvironmentMapLight::solid_color(image_assets.as_mut(), ambient.color)
})
.insert(EnvironmentMapLightFromAmbientLight);
}
}
for (mut env_map, ambient_override) in managed_views.iter_mut() {
let ambient = ambient_override.as_ref().unwrap_or(&ambient_light);
let ambient_required = ambient.brightness > 0.0 && ambient.color != Color::BLACK;
if ambient_required && ambient.is_changed() {
*env_map = EnvironmentMapLight {
intensity: ambient.brightness,
affects_lightmapped_mesh_diffuse: ambient.affects_lightmapped_meshes,
..EnvironmentMapLight::solid_color(image_assets.as_mut(), ambient.color)
};
}
}
}
pub fn update_directional_light_frusta( pub fn update_directional_light_frusta(
mut views: Query< mut views: Query<
( (

View File

@ -44,7 +44,8 @@
//! //!
//! [several pre-filtered environment maps]: https://github.com/KhronosGroup/glTF-Sample-Environments //! [several pre-filtered environment maps]: https://github.com/KhronosGroup/glTF-Sample-Environments
use bevy_asset::{weak_handle, AssetId, Handle}; use bevy_asset::{weak_handle, AssetId, Assets, Handle, RenderAssetUsages};
use bevy_color::{Color, ColorToPacked, Srgba};
use bevy_ecs::{ use bevy_ecs::{
component::Component, query::QueryItem, reflect::ReflectComponent, system::lifetimeless::Read, component::Component, query::QueryItem, reflect::ReflectComponent, system::lifetimeless::Read,
}; };
@ -56,8 +57,9 @@ use bevy_render::{
render_asset::RenderAssets, render_asset::RenderAssets,
render_resource::{ render_resource::{
binding_types::{self, uniform_buffer}, binding_types::{self, uniform_buffer},
BindGroupLayoutEntryBuilder, Sampler, SamplerBindingType, Shader, ShaderStages, BindGroupLayoutEntryBuilder, Extent3d, Sampler, SamplerBindingType, Shader, ShaderStages,
TextureSampleType, TextureView, TextureDimension, TextureFormat, TextureSampleType, TextureView, TextureViewDescriptor,
TextureViewDimension,
}, },
renderer::{RenderAdapter, RenderDevice}, renderer::{RenderAdapter, RenderDevice},
texture::{FallbackImage, GpuImage}, texture::{FallbackImage, GpuImage},
@ -114,6 +116,83 @@ pub struct EnvironmentMapLight {
pub affects_lightmapped_mesh_diffuse: bool, pub affects_lightmapped_mesh_diffuse: bool,
} }
impl EnvironmentMapLight {
/// An environment map with a uniform color, useful for uniform ambient lighting.
pub fn solid_color(assets: &mut Assets<Image>, color: Color) -> Self {
let color: Srgba = color.into();
let image = Image {
texture_view_descriptor: Some(TextureViewDescriptor {
dimension: Some(TextureViewDimension::Cube),
..Default::default()
}),
..Image::new_fill(
Extent3d {
width: 1,
height: 1,
depth_or_array_layers: 6,
},
TextureDimension::D2,
&color.to_u8_array(),
TextureFormat::Rgba8UnormSrgb,
RenderAssetUsages::RENDER_WORLD,
)
};
let handle = assets.add(image);
Self {
diffuse_map: handle.clone(),
specular_map: handle,
..Default::default()
}
}
/// An environment map with a hemispherical gradient, fading between the sky and ground colors
/// at the horizon. Useful as a very simple 'sky'.
pub fn hemispherical_gradient(
assets: &mut Assets<Image>,
top_color: Color,
bottom_color: Color,
) -> Self {
let top_color: Srgba = top_color.into();
let bottom_color: Srgba = bottom_color.into();
let mid_color = (top_color + bottom_color) / 2.0;
let image = Image {
texture_view_descriptor: Some(TextureViewDescriptor {
dimension: Some(TextureViewDimension::Cube),
..Default::default()
}),
..Image::new(
Extent3d {
width: 1,
height: 1,
depth_or_array_layers: 6,
},
TextureDimension::D2,
[
mid_color,
mid_color,
top_color,
bottom_color,
mid_color,
mid_color,
]
.into_iter()
.flat_map(Srgba::to_u8_array)
.collect(),
TextureFormat::Rgba8UnormSrgb,
RenderAssetUsages::RENDER_WORLD,
)
};
let handle = assets.add(image);
Self {
diffuse_map: handle.clone(),
specular_map: handle,
..Default::default()
}
}
}
impl Default for EnvironmentMapLight { impl Default for EnvironmentMapLight {
fn default() -> Self { fn default() -> Self {
EnvironmentMapLight { EnvironmentMapLight {

View File

@ -139,7 +139,6 @@ bitflags::bitflags! {
#[derive(Copy, Clone, Debug, ShaderType)] #[derive(Copy, Clone, Debug, ShaderType)]
pub struct GpuLights { pub struct GpuLights {
directional_lights: [GpuDirectionalLight; MAX_DIRECTIONAL_LIGHTS], directional_lights: [GpuDirectionalLight; MAX_DIRECTIONAL_LIGHTS],
ambient_color: Vec4,
// xyz are x/y/z cluster dimensions and w is the number of clusters // xyz are x/y/z cluster dimensions and w is the number of clusters
cluster_dimensions: UVec4, cluster_dimensions: UVec4,
// xy are vec2<f32>(cluster_dimensions.xy) / vec2<f32>(view.width, view.height) // xy are vec2<f32>(cluster_dimensions.xy) / vec2<f32>(view.width, view.height)
@ -149,7 +148,6 @@ pub struct GpuLights {
n_directional_lights: u32, n_directional_lights: u32,
// offset from spot light's light index to spot light's shadow map index // offset from spot light's light index to spot light's shadow map index
spot_light_shadowmap_offset: i32, spot_light_shadowmap_offset: i32,
ambient_light_affects_lightmapped_meshes: u32,
} }
// NOTE: When running bevy on Adreno GPU chipsets in WebGL, any value above 1 will result in a crash // NOTE: When running bevy on Adreno GPU chipsets in WebGL, any value above 1 will result in a crash
@ -729,11 +727,9 @@ pub fn prepare_lights(
&ExtractedClusterConfig, &ExtractedClusterConfig,
Option<&RenderLayers>, Option<&RenderLayers>,
Has<NoIndirectDrawing>, Has<NoIndirectDrawing>,
Option<&AmbientLight>,
), ),
With<Camera3d>, With<Camera3d>,
>, >,
ambient_light: Res<AmbientLight>,
point_light_shadow_map: Res<PointLightShadowMap>, point_light_shadow_map: Res<PointLightShadowMap>,
directional_light_shadow_map: Res<DirectionalLightShadowMap>, directional_light_shadow_map: Res<DirectionalLightShadowMap>,
mut shadow_render_phases: ResMut<ViewBinnedRenderPhases<Shadow>>, mut shadow_render_phases: ResMut<ViewBinnedRenderPhases<Shadow>>,
@ -1142,15 +1138,8 @@ pub fn prepare_lights(
let mut live_views = EntityHashSet::with_capacity(views_count); let mut live_views = EntityHashSet::with_capacity(views_count);
// set up light data for each view // set up light data for each view
for ( for (entity, camera_main_entity, extracted_view, clusters, maybe_layers, no_indirect_drawing) in
entity, sorted_cameras
camera_main_entity,
extracted_view,
clusters,
maybe_layers,
no_indirect_drawing,
maybe_ambient_override,
) in sorted_cameras
.0 .0
.iter() .iter()
.filter_map(|sorted_camera| views.get(sorted_camera.entity).ok()) .filter_map(|sorted_camera| views.get(sorted_camera.entity).ok())
@ -1175,11 +1164,8 @@ pub fn prepare_lights(
); );
let n_clusters = clusters.dimensions.x * clusters.dimensions.y * clusters.dimensions.z; let n_clusters = clusters.dimensions.x * clusters.dimensions.y * clusters.dimensions.z;
let ambient_light = maybe_ambient_override.unwrap_or(&ambient_light);
let mut gpu_lights = GpuLights { let mut gpu_lights = GpuLights {
directional_lights: gpu_directional_lights, directional_lights: gpu_directional_lights,
ambient_color: Vec4::from_slice(&LinearRgba::from(ambient_light.color).to_f32_array())
* ambient_light.brightness,
cluster_factors: Vec4::new( cluster_factors: Vec4::new(
clusters.dimensions.x as f32 / extracted_view.viewport.z as f32, clusters.dimensions.x as f32 / extracted_view.viewport.z as f32,
clusters.dimensions.y as f32 / extracted_view.viewport.w as f32, clusters.dimensions.y as f32 / extracted_view.viewport.w as f32,
@ -1194,8 +1180,6 @@ pub fn prepare_lights(
// index to shadow map index, we need to subtract point light count and add directional shadowmap count. // index to shadow map index, we need to subtract point light count and add directional shadowmap count.
spot_light_shadowmap_offset: num_directional_cascades_enabled as i32 spot_light_shadowmap_offset: num_directional_cascades_enabled as i32
- point_light_count as i32, - point_light_count as i32,
ambient_light_affects_lightmapped_meshes: ambient_light.affects_lightmapped_meshes
as u32,
}; };
// TODO: this should select lights based on relevance to the view instead of the first ones that show up in a query // TODO: this should select lights based on relevance to the view instead of the first ones that show up in a query

View File

@ -50,7 +50,6 @@ const DIRECTIONAL_LIGHT_FLAGS_AFFECTS_LIGHTMAPPED_MESH_DIFFUSE_BIT: u32 = 4u;
struct Lights { struct Lights {
// NOTE: this array size must be kept in sync with the constants defined in bevy_pbr/src/render/light.rs // NOTE: this array size must be kept in sync with the constants defined in bevy_pbr/src/render/light.rs
directional_lights: array<DirectionalLight, #{MAX_DIRECTIONAL_LIGHTS}u>, directional_lights: array<DirectionalLight, #{MAX_DIRECTIONAL_LIGHTS}u>,
ambient_color: vec4<f32>,
// x/y/z dimensions and n_clusters in w // x/y/z dimensions and n_clusters in w
cluster_dimensions: vec4<u32>, cluster_dimensions: vec4<u32>,
// xy are vec2<f32>(cluster_dimensions.xy) / vec2<f32>(view.width, view.height) // xy are vec2<f32>(cluster_dimensions.xy) / vec2<f32>(view.width, view.height)

View File

@ -1,29 +0,0 @@
#define_import_path bevy_pbr::ambient
#import bevy_pbr::{
lighting::{EnvBRDFApprox, F_AB},
mesh_view_bindings::lights,
}
// A precomputed `NdotV` is provided because it is computed regardless,
// but `world_normal` and the view vector `V` are provided separately for more advanced uses.
fn ambient_light(
world_position: vec4<f32>,
world_normal: vec3<f32>,
V: vec3<f32>,
NdotV: f32,
diffuse_color: vec3<f32>,
specular_color: vec3<f32>,
perceptual_roughness: f32,
occlusion: vec3<f32>,
) -> vec3<f32> {
let diffuse_ambient = EnvBRDFApprox(diffuse_color, F_AB(1.0, NdotV));
let specular_ambient = EnvBRDFApprox(specular_color, F_AB(perceptual_roughness, NdotV));
// No real world material has specular values under 0.02, so we use this range as a
// "pre-baked specular occlusion" that extinguishes the fresnel term, for artistic control.
// See: https://google.github.io/filament/Filament.html#specularocclusion
let specular_occlusion = saturate(dot(specular_color, vec3(50.0 * 0.33)));
return (diffuse_ambient + specular_ambient * specular_occlusion) * lights.ambient_color.rgb * occlusion;
}

View File

@ -561,18 +561,6 @@ fn apply_pbr_lighting(
#endif #endif
} }
#ifdef STANDARD_MATERIAL_DIFFUSE_TRANSMISSION
// NOTE: We use the diffuse transmissive color, the second Lambertian lobe's calculated
// world position, inverted normal and view vectors, and the following simplified
// values for a fully diffuse transmitted light contribution approximation:
//
// perceptual_roughness = 1.0;
// NdotV = 1.0;
// F0 = vec3<f32>(0.0)
// diffuse_occlusion = vec3<f32>(1.0)
transmitted_light += ambient::ambient_light(diffuse_transmissive_lobe_world_position, -in.N, -in.V, 1.0, diffuse_transmissive_color, vec3<f32>(0.0), 1.0, vec3<f32>(1.0));
#endif
// Diffuse indirect lighting can come from a variety of sources. The // Diffuse indirect lighting can come from a variety of sources. The
// priority goes like this: // priority goes like this:
// //
@ -644,9 +632,6 @@ fn apply_pbr_lighting(
#endif // ENVIRONMENT_MAP #endif // ENVIRONMENT_MAP
// Ambient light (indirect)
indirect_light += ambient::ambient_light(in.world_position, in.N, in.V, NdotV, diffuse_color, F0, perceptual_roughness, diffuse_occlusion);
// we'll use the specular component of the transmitted environment // we'll use the specular component of the transmitted environment
// light in the call to `specular_transmissive_light()` below // light in the call to `specular_transmissive_light()` below
var specular_transmitted_environment_light = vec3<f32>(0.0); var specular_transmitted_environment_light = vec3<f32>(0.0);

View File

@ -24,11 +24,6 @@ const ATTRIBUTE_BARYCENTRIC: MeshVertexAttribute =
fn main() { fn main() {
App::new() App::new()
.insert_resource(AmbientLight {
color: Color::WHITE,
brightness: 1.0 / 5.0f32,
..default()
})
.add_plugins(( .add_plugins((
DefaultPlugins.set( DefaultPlugins.set(
GltfPlugin::default() GltfPlugin::default()
@ -48,6 +43,7 @@ fn setup(
mut commands: Commands, mut commands: Commands,
asset_server: Res<AssetServer>, asset_server: Res<AssetServer>,
mut materials: ResMut<Assets<CustomMaterial>>, mut materials: ResMut<Assets<CustomMaterial>>,
mut images: ResMut<Assets<Image>>,
) { ) {
// Add a mesh loaded from a glTF file. This mesh has data for `ATTRIBUTE_BARYCENTRIC`. // Add a mesh loaded from a glTF file. This mesh has data for `ATTRIBUTE_BARYCENTRIC`.
let mesh = asset_server.load( let mesh = asset_server.load(
@ -63,7 +59,13 @@ fn setup(
Transform::from_scale(150.0 * Vec3::ONE), Transform::from_scale(150.0 * Vec3::ONE),
)); ));
commands.spawn(Camera2d); commands.spawn((
Camera2d,
EnvironmentMapLight {
intensity: 1.0 / 5.0,
..EnvironmentMapLight::solid_color(&mut images, Color::WHITE)
},
));
} }
/// This custom material uses barycentric coordinates from /// This custom material uses barycentric coordinates from

View File

@ -101,11 +101,11 @@ fn setup(
} }
} }
commands.insert_resource(AmbientLight { #[expect(
color: Color::WHITE, deprecated,
brightness: 0.0, reason = "Once AmbientLight is removed, the resource can be removed"
..default() )]
}); commands.insert_resource(AmbientLight::NONE);
commands.spawn(( commands.spawn((
PointLight { PointLight {

View File

@ -21,6 +21,10 @@ use bevy::{
}; };
fn main() { fn main() {
#[expect(
deprecated,
reason = "Once AmbientLight is removed, the resource can be removed"
)]
App::new() App::new()
.insert_resource(AmbientLight::NONE) .insert_resource(AmbientLight::NONE)
.add_plugins(DefaultPlugins) .add_plugins(DefaultPlugins)

View File

@ -13,6 +13,10 @@ use bevy::{
/// Entry point. /// Entry point.
fn main() { fn main() {
#[expect(
deprecated,
reason = "Once AmbientLight is removed, the resource can be removed"
)]
App::new() App::new()
.add_plugins(DefaultPlugins.set(WindowPlugin { .add_plugins(DefaultPlugins.set(WindowPlugin {
primary_window: Some(Window { primary_window: Some(Window {

View File

@ -157,11 +157,6 @@ fn main() {
.add_plugins(MaterialPlugin::<VoxelVisualizationMaterial>::default()) .add_plugins(MaterialPlugin::<VoxelVisualizationMaterial>::default())
.init_resource::<AppStatus>() .init_resource::<AppStatus>()
.init_resource::<ExampleAssets>() .init_resource::<ExampleAssets>()
.insert_resource(AmbientLight {
color: Color::WHITE,
brightness: 0.0,
..default()
})
.add_systems(Startup, setup) .add_systems(Startup, setup)
.add_systems(PreUpdate, create_cubes) .add_systems(PreUpdate, create_cubes)
.add_systems(Update, rotate_camera) .add_systems(Update, rotate_camera)
@ -216,9 +211,14 @@ fn main() {
} }
// Spawns all the scene objects. // Spawns all the scene objects.
fn setup(mut commands: Commands, assets: Res<ExampleAssets>, app_status: Res<AppStatus>) { fn setup(
mut commands: Commands,
images: ResMut<Assets<Image>>,
assets: Res<ExampleAssets>,
app_status: Res<AppStatus>,
) {
spawn_main_scene(&mut commands, &assets); spawn_main_scene(&mut commands, &assets);
spawn_camera(&mut commands, &assets); spawn_camera(&mut commands, images, &assets);
spawn_irradiance_volume(&mut commands, &assets); spawn_irradiance_volume(&mut commands, &assets);
spawn_light(&mut commands); spawn_light(&mut commands);
spawn_sphere(&mut commands, &assets); spawn_sphere(&mut commands, &assets);
@ -231,7 +231,11 @@ fn spawn_main_scene(commands: &mut Commands, assets: &ExampleAssets) {
commands.spawn(SceneRoot(assets.main_scene.clone())); commands.spawn(SceneRoot(assets.main_scene.clone()));
} }
fn spawn_camera(commands: &mut Commands, assets: &ExampleAssets) { fn spawn_camera(
commands: &mut Commands,
mut images: ResMut<Assets<Image>>,
assets: &ExampleAssets,
) {
commands.spawn(( commands.spawn((
Camera3d::default(), Camera3d::default(),
Transform::from_xyz(-10.012, 4.8605, 13.281).looking_at(Vec3::ZERO, Vec3::Y), Transform::from_xyz(-10.012, 4.8605, 13.281).looking_at(Vec3::ZERO, Vec3::Y),
@ -240,6 +244,10 @@ fn spawn_camera(commands: &mut Commands, assets: &ExampleAssets) {
brightness: 150.0, brightness: 150.0,
..default() ..default()
}, },
EnvironmentMapLight {
intensity: 0.0,
..EnvironmentMapLight::solid_color(&mut images, Color::WHITE)
},
)); ));
} }
@ -415,7 +423,7 @@ fn toggle_irradiance_volumes(
light_probe_query: Query<Entity, With<LightProbe>>, light_probe_query: Query<Entity, With<LightProbe>>,
mut app_status: ResMut<AppStatus>, mut app_status: ResMut<AppStatus>,
assets: Res<ExampleAssets>, assets: Res<ExampleAssets>,
mut ambient_light: ResMut<AmbientLight>, mut ambient_light: Query<&mut EnvironmentMapLight>,
) { ) {
if !keyboard.just_pressed(KeyCode::Space) { if !keyboard.just_pressed(KeyCode::Space) {
return; return;
@ -427,7 +435,9 @@ fn toggle_irradiance_volumes(
if app_status.irradiance_volume_present { if app_status.irradiance_volume_present {
commands.entity(light_probe).remove::<IrradianceVolume>(); commands.entity(light_probe).remove::<IrradianceVolume>();
ambient_light.brightness = AMBIENT_LIGHT_BRIGHTNESS * IRRADIANCE_VOLUME_INTENSITY; for mut light in ambient_light.iter_mut() {
light.intensity = AMBIENT_LIGHT_BRIGHTNESS * IRRADIANCE_VOLUME_INTENSITY;
}
app_status.irradiance_volume_present = false; app_status.irradiance_volume_present = false;
} else { } else {
commands.entity(light_probe).insert(IrradianceVolume { commands.entity(light_probe).insert(IrradianceVolume {
@ -435,7 +445,9 @@ fn toggle_irradiance_volumes(
intensity: IRRADIANCE_VOLUME_INTENSITY, intensity: IRRADIANCE_VOLUME_INTENSITY,
..default() ..default()
}); });
ambient_light.brightness = 0.0; for mut light in ambient_light.iter_mut() {
light.intensity = 0.0;
}
app_status.irradiance_volume_present = true; app_status.irradiance_volume_present = true;
} }
} }

View File

@ -35,6 +35,7 @@ fn setup(
parameters: Res<Parameters>, parameters: Res<Parameters>,
mut commands: Commands, mut commands: Commands,
mut meshes: ResMut<Assets<Mesh>>, mut meshes: ResMut<Assets<Mesh>>,
mut images: ResMut<Assets<Image>>,
mut materials: ResMut<Assets<StandardMaterial>>, mut materials: ResMut<Assets<StandardMaterial>>,
asset_server: Res<AssetServer>, asset_server: Res<AssetServer>,
) { ) {
@ -110,13 +111,6 @@ fn setup(
Movable, Movable,
)); ));
// ambient light
commands.insert_resource(AmbientLight {
color: ORANGE_RED.into(),
brightness: 0.02,
..default()
});
// red point light // red point light
commands.spawn(( commands.spawn((
PointLight { PointLight {
@ -236,6 +230,10 @@ fn setup(
Camera3d::default(), Camera3d::default(),
Transform::from_xyz(-2.0, 2.5, 5.0).looking_at(Vec3::ZERO, Vec3::Y), Transform::from_xyz(-2.0, 2.5, 5.0).looking_at(Vec3::ZERO, Vec3::Y),
Exposure::from_physical_camera(**parameters), Exposure::from_physical_camera(**parameters),
EnvironmentMapLight {
intensity: 0.02,
..EnvironmentMapLight::solid_color(&mut images, ORANGE_RED.into())
},
)); ));
} }

View File

@ -25,6 +25,10 @@ fn main() {
let args: Args = Args::from_args(&[], &[]).unwrap(); let args: Args = Args::from_args(&[], &[]).unwrap();
let mut app = App::new(); let mut app = App::new();
#[expect(
deprecated,
reason = "Once AmbientLight is removed, the resource can be removed"
)]
app.add_plugins(DefaultPlugins) app.add_plugins(DefaultPlugins)
.insert_resource(AmbientLight::NONE); .insert_resource(AmbientLight::NONE);

View File

@ -123,11 +123,6 @@ fn main() {
..default() ..default()
})) }))
.add_plugins(MeshPickingPlugin) .add_plugins(MeshPickingPlugin)
.insert_resource(AmbientLight {
color: ClearColor::default().0,
brightness: 10000.0,
affects_lightmapped_meshes: true,
})
.init_resource::<AppStatus>() .init_resource::<AppStatus>()
.add_event::<WidgetClickEvent<LightingMode>>() .add_event::<WidgetClickEvent<LightingMode>>()
.add_event::<LightingModeChanged>() .add_event::<LightingModeChanged>()
@ -145,18 +140,28 @@ fn main() {
} }
/// Creates the scene. /// Creates the scene.
fn setup(mut commands: Commands, asset_server: Res<AssetServer>, app_status: Res<AppStatus>) { fn setup(
spawn_camera(&mut commands); mut commands: Commands,
images: ResMut<Assets<Image>>,
asset_server: Res<AssetServer>,
app_status: Res<AppStatus>,
) {
spawn_camera(&mut commands, images);
spawn_scene(&mut commands, &asset_server); spawn_scene(&mut commands, &asset_server);
spawn_buttons(&mut commands); spawn_buttons(&mut commands);
spawn_help_text(&mut commands, &app_status); spawn_help_text(&mut commands, &app_status);
} }
/// Spawns the 3D camera. /// Spawns the 3D camera.
fn spawn_camera(commands: &mut Commands) { fn spawn_camera(commands: &mut Commands, mut images: ResMut<Assets<Image>>) {
commands commands.spawn((
.spawn(Camera3d::default()) Camera3d::default(),
.insert(Transform::from_xyz(-0.7, 0.7, 1.0).looking_at(vec3(0.0, 0.3, 0.0), Vec3::Y)); Transform::from_xyz(-0.7, 0.7, 1.0).looking_at(vec3(0.0, 0.3, 0.0), Vec3::Y),
EnvironmentMapLight {
intensity: 10000.0,
..EnvironmentMapLight::solid_color(&mut images, ClearColor::default().0)
},
));
} }
/// Spawns the scene. /// Spawns the scene.

View File

@ -17,7 +17,7 @@ fn main() {
.run(); .run();
} }
fn setup_camera(mut commands: Commands) { fn setup_camera(mut commands: Commands, mut images: ResMut<Assets<Image>>) {
commands.spawn(( commands.spawn((
Camera3d::default(), Camera3d::default(),
// Add the `MotionBlur` component to a camera to enable motion blur. // Add the `MotionBlur` component to a camera to enable motion blur.
@ -32,6 +32,10 @@ fn setup_camera(mut commands: Commands) {
// MSAA and Motion Blur together are not compatible on WebGL // MSAA and Motion Blur together are not compatible on WebGL
#[cfg(all(feature = "webgl2", target_arch = "wasm32", not(feature = "webgpu")))] #[cfg(all(feature = "webgl2", target_arch = "wasm32", not(feature = "webgpu")))]
Msaa::Off, Msaa::Off,
EnvironmentMapLight {
intensity: 300.0,
..EnvironmentMapLight::solid_color(&mut images, Color::WHITE)
},
)); ));
} }
@ -59,11 +63,6 @@ fn setup_scene(
mut meshes: ResMut<Assets<Mesh>>, mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<StandardMaterial>>, mut materials: ResMut<Assets<StandardMaterial>>,
) { ) {
commands.insert_resource(AmbientLight {
color: Color::WHITE,
brightness: 300.0,
..default()
});
commands.insert_resource(CameraMode::Chase); commands.insert_resource(CameraMode::Chase);
commands.spawn(( commands.spawn((
DirectionalLight { DirectionalLight {

View File

@ -57,7 +57,11 @@ struct Cubemap {
image_handle: Handle<Image>, image_handle: Handle<Image>,
} }
fn setup(mut commands: Commands, asset_server: Res<AssetServer>) { fn setup(
mut commands: Commands,
asset_server: Res<AssetServer>,
mut images: ResMut<Assets<Image>>,
) {
// directional 'sun' light // directional 'sun' light
commands.spawn(( commands.spawn((
DirectionalLight { DirectionalLight {
@ -78,17 +82,15 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
brightness: 1000.0, brightness: 1000.0,
..default() ..default()
}, },
// This should ideally be using a convolved environment map for diffuse, but for simplicity
// we're just using a solid color here.
EnvironmentMapLight {
intensity: 1.0,
specular_map: skybox_handle.clone(),
..EnvironmentMapLight::solid_color(&mut images, Color::srgb_u8(210, 220, 240))
},
)); ));
// 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 {
color: Color::srgb_u8(210, 220, 240),
brightness: 1.0,
..default()
});
commands.insert_resource(Cubemap { commands.insert_resource(Cubemap {
is_loaded: false, is_loaded: false,
index: 0, index: 0,

View File

@ -49,6 +49,10 @@ enum TintType {
/// The entry point. /// The entry point.
fn main() { fn main() {
#[expect(
deprecated,
reason = "Once AmbientLight is removed, the resource can be removed"
)]
App::new() App::new()
.add_plugins(DefaultPlugins.set(WindowPlugin { .add_plugins(DefaultPlugins.set(WindowPlugin {
primary_window: Some(Window { primary_window: Some(Window {
@ -59,11 +63,7 @@ fn main() {
})) }))
.init_resource::<AppAssets>() .init_resource::<AppAssets>()
.init_resource::<AppStatus>() .init_resource::<AppStatus>()
.insert_resource(AmbientLight { .insert_resource(AmbientLight::NONE)
color: Color::BLACK,
brightness: 0.0,
..default()
})
.add_systems(Startup, setup) .add_systems(Startup, setup)
.add_systems(Update, rotate_camera) .add_systems(Update, rotate_camera)
.add_systems(Update, (toggle_specular_map, update_text).chain()) .add_systems(Update, (toggle_specular_map, update_text).chain())

View File

@ -4,10 +4,6 @@ use bevy::prelude::*;
fn main() { fn main() {
App::new() App::new()
.insert_resource(AmbientLight {
brightness: 60.0,
..default()
})
.add_plugins(DefaultPlugins) .add_plugins(DefaultPlugins)
.add_systems(Startup, setup) .add_systems(Startup, setup)
.run(); .run();
@ -16,12 +12,17 @@ fn main() {
fn setup( fn setup(
mut commands: Commands, mut commands: Commands,
mut meshes: ResMut<Assets<Mesh>>, mut meshes: ResMut<Assets<Mesh>>,
mut images: ResMut<Assets<Image>>,
mut materials: ResMut<Assets<StandardMaterial>>, mut materials: ResMut<Assets<StandardMaterial>>,
) { ) {
// camera // camera
commands.spawn(( commands.spawn((
Camera3d::default(), Camera3d::default(),
Transform::from_xyz(0.2, 1.5, 2.5).looking_at(Vec3::ZERO, Vec3::Y), Transform::from_xyz(0.2, 1.5, 2.5).looking_at(Vec3::ZERO, Vec3::Y),
EnvironmentMapLight {
intensity: 60.0,
..EnvironmentMapLight::solid_color(&mut images, Color::WHITE)
},
)); ));
// plane // plane

View File

@ -20,10 +20,6 @@ Rotate Camera: Left and Right Arrows";
fn main() { fn main() {
App::new() App::new()
.insert_resource(AmbientLight {
brightness: 20.0,
..default()
})
.add_plugins(DefaultPlugins) .add_plugins(DefaultPlugins)
.add_systems(Startup, setup) .add_systems(Startup, setup)
.add_systems(Update, (light_sway, movement, rotation)) .add_systems(Update, (light_sway, movement, rotation))
@ -37,6 +33,7 @@ struct Movable;
fn setup( fn setup(
mut commands: Commands, mut commands: Commands,
mut meshes: ResMut<Assets<Mesh>>, mut meshes: ResMut<Assets<Mesh>>,
mut images: ResMut<Assets<Image>>,
mut materials: ResMut<Assets<StandardMaterial>>, mut materials: ResMut<Assets<StandardMaterial>>,
) { ) {
// ground plane // ground plane
@ -124,6 +121,10 @@ fn setup(
..default() ..default()
}, },
Transform::from_xyz(-4.0, 5.0, 10.0).looking_at(Vec3::ZERO, Vec3::Y), Transform::from_xyz(-4.0, 5.0, 10.0).looking_at(Vec3::ZERO, Vec3::Y),
EnvironmentMapLight {
intensity: 20.0,
..EnvironmentMapLight::solid_color(&mut images, Color::WHITE)
},
)); ));
commands.spawn(( commands.spawn((

View File

@ -11,10 +11,6 @@ use std::f32::consts::PI;
fn main() { fn main() {
App::new() App::new()
.insert_resource(AmbientLight {
brightness: 1000.,
..default()
})
.add_plugins((DefaultPlugins, TemporalAntiAliasPlugin)) .add_plugins((DefaultPlugins, TemporalAntiAliasPlugin))
.add_systems(Startup, setup) .add_systems(Startup, setup)
.add_systems(Update, update) .add_systems(Update, update)
@ -24,6 +20,7 @@ fn main() {
fn setup( fn setup(
mut commands: Commands, mut commands: Commands,
mut meshes: ResMut<Assets<Mesh>>, mut meshes: ResMut<Assets<Mesh>>,
mut images: ResMut<Assets<Image>>,
mut materials: ResMut<Assets<StandardMaterial>>, mut materials: ResMut<Assets<StandardMaterial>>,
) { ) {
commands.spawn(( commands.spawn((
@ -36,6 +33,10 @@ fn setup(
Msaa::Off, Msaa::Off,
ScreenSpaceAmbientOcclusion::default(), ScreenSpaceAmbientOcclusion::default(),
TemporalAntiAliasing::default(), TemporalAntiAliasing::default(),
EnvironmentMapLight {
intensity: 1000.0,
..EnvironmentMapLight::solid_color(&mut images, Color::WHITE)
},
)); ));
let material = materials.add(StandardMaterial { let material = materials.add(StandardMaterial {

View File

@ -42,13 +42,14 @@ use rand::random;
fn main() { fn main() {
let mut app = App::new(); let mut app = App::new();
#[expect(
deprecated,
reason = "Once AmbientLight is removed, the resource can be removed"
)]
app.add_plugins(DefaultPlugins) app.add_plugins(DefaultPlugins)
.insert_resource(ClearColor(Color::BLACK)) .insert_resource(ClearColor(Color::BLACK))
.insert_resource(PointLightShadowMap { size: 2048 }) .insert_resource(PointLightShadowMap { size: 2048 })
.insert_resource(AmbientLight { .insert_resource(AmbientLight::NONE)
brightness: 0.0,
..default()
})
.add_systems(Startup, setup) .add_systems(Startup, setup)
.add_systems(Update, (example_control_system, flicker_system)); .add_systems(Update, (example_control_system, flicker_system));

View File

@ -37,6 +37,10 @@ struct MoveBackAndForthHorizontally {
} }
fn main() { fn main() {
#[expect(
deprecated,
reason = "Once AmbientLight is removed, the resource can be removed"
)]
App::new() App::new()
.add_plugins(DefaultPlugins) .add_plugins(DefaultPlugins)
.insert_resource(ClearColor(Color::Srgba(Srgba { .insert_resource(ClearColor(Color::Srgba(Srgba {

View File

@ -9,11 +9,6 @@ const GLTF_PATH: &str = "models/animated/Fox.glb";
fn main() { fn main() {
App::new() App::new()
.insert_resource(AmbientLight {
color: Color::WHITE,
brightness: 2000.,
..default()
})
.add_plugins(DefaultPlugins) .add_plugins(DefaultPlugins)
.add_systems(Startup, setup_mesh_and_animation) .add_systems(Startup, setup_mesh_and_animation)
.add_systems(Startup, setup_camera_and_environment) .add_systems(Startup, setup_camera_and_environment)
@ -98,12 +93,17 @@ fn play_animation_when_ready(
fn setup_camera_and_environment( fn setup_camera_and_environment(
mut commands: Commands, mut commands: Commands,
mut meshes: ResMut<Assets<Mesh>>, mut meshes: ResMut<Assets<Mesh>>,
mut images: ResMut<Assets<Image>>,
mut materials: ResMut<Assets<StandardMaterial>>, mut materials: ResMut<Assets<StandardMaterial>>,
) { ) {
// Camera // Camera
commands.spawn(( commands.spawn((
Camera3d::default(), Camera3d::default(),
Transform::from_xyz(100.0, 100.0, 150.0).looking_at(Vec3::new(0.0, 20.0, 0.0), Vec3::Y), Transform::from_xyz(100.0, 100.0, 150.0).looking_at(Vec3::new(0.0, 20.0, 0.0), Vec3::Y),
EnvironmentMapLight {
intensity: 2000.0,
..EnvironmentMapLight::solid_color(&mut images, Color::WHITE)
},
)); ));
// Plane // Plane

View File

@ -8,11 +8,6 @@ const FOX_PATH: &str = "models/animated/Fox.glb";
fn main() { fn main() {
App::new() App::new()
.insert_resource(AmbientLight {
color: Color::WHITE,
brightness: 2000.,
..default()
})
.add_plugins(DefaultPlugins) .add_plugins(DefaultPlugins)
.add_systems(Startup, setup) .add_systems(Startup, setup)
.add_systems(Update, setup_scene_once_loaded) .add_systems(Update, setup_scene_once_loaded)
@ -30,6 +25,7 @@ fn setup(
mut commands: Commands, mut commands: Commands,
asset_server: Res<AssetServer>, asset_server: Res<AssetServer>,
mut meshes: ResMut<Assets<Mesh>>, mut meshes: ResMut<Assets<Mesh>>,
mut images: ResMut<Assets<Image>>,
mut materials: ResMut<Assets<StandardMaterial>>, mut materials: ResMut<Assets<StandardMaterial>>,
mut graphs: ResMut<Assets<AnimationGraph>>, mut graphs: ResMut<Assets<AnimationGraph>>,
) { ) {
@ -52,6 +48,10 @@ fn setup(
commands.spawn(( commands.spawn((
Camera3d::default(), Camera3d::default(),
Transform::from_xyz(100.0, 100.0, 150.0).looking_at(Vec3::new(0.0, 20.0, 0.0), Vec3::Y), Transform::from_xyz(100.0, 100.0, 150.0).looking_at(Vec3::new(0.0, 20.0, 0.0), Vec3::Y),
EnvironmentMapLight {
intensity: 2000.0,
..EnvironmentMapLight::solid_color(&mut images, Color::WHITE)
},
)); ));
// Plane // Plane

View File

@ -13,11 +13,6 @@ const FOX_PATH: &str = "models/animated/Fox.glb";
fn main() { fn main() {
App::new() App::new()
.insert_resource(AmbientLight {
color: Color::WHITE,
brightness: 2000.,
..default()
})
.add_plugins(DefaultPlugins) .add_plugins(DefaultPlugins)
.init_resource::<ParticleAssets>() .init_resource::<ParticleAssets>()
.init_resource::<FoxFeetTargets>() .init_resource::<FoxFeetTargets>()
@ -78,6 +73,7 @@ fn setup(
mut commands: Commands, mut commands: Commands,
asset_server: Res<AssetServer>, asset_server: Res<AssetServer>,
mut meshes: ResMut<Assets<Mesh>>, mut meshes: ResMut<Assets<Mesh>>,
mut images: ResMut<Assets<Image>>,
mut materials: ResMut<Assets<StandardMaterial>>, mut materials: ResMut<Assets<StandardMaterial>>,
mut graphs: ResMut<Assets<AnimationGraph>>, mut graphs: ResMut<Assets<AnimationGraph>>,
) { ) {
@ -98,6 +94,10 @@ fn setup(
commands.spawn(( commands.spawn((
Camera3d::default(), Camera3d::default(),
Transform::from_xyz(100.0, 100.0, 150.0).looking_at(Vec3::new(0.0, 20.0, 0.0), Vec3::Y), Transform::from_xyz(100.0, 100.0, 150.0).looking_at(Vec3::new(0.0, 20.0, 0.0), Vec3::Y),
EnvironmentMapLight {
intensity: 2000.0,
..EnvironmentMapLight::solid_color(&mut images, Color::WHITE)
},
)); ));
// Plane // Plane

View File

@ -10,11 +10,6 @@ use bevy::{
fn main() { fn main() {
App::new() App::new()
.add_plugins(DefaultPlugins) .add_plugins(DefaultPlugins)
.insert_resource(AmbientLight {
color: Color::WHITE,
brightness: 150.0,
..default()
})
.add_systems(Startup, setup) .add_systems(Startup, setup)
.run(); .run();
} }
@ -22,6 +17,7 @@ fn main() {
fn setup( fn setup(
mut commands: Commands, mut commands: Commands,
mut meshes: ResMut<Assets<Mesh>>, mut meshes: ResMut<Assets<Mesh>>,
mut images: ResMut<Assets<Image>>,
mut materials: ResMut<Assets<StandardMaterial>>, mut materials: ResMut<Assets<StandardMaterial>>,
mut animations: ResMut<Assets<AnimationClip>>, mut animations: ResMut<Assets<AnimationClip>>,
mut graphs: ResMut<Assets<AnimationGraph>>, mut graphs: ResMut<Assets<AnimationGraph>>,
@ -30,6 +26,10 @@ fn setup(
commands.spawn(( commands.spawn((
Camera3d::default(), Camera3d::default(),
Transform::from_xyz(-2.0, 2.5, 5.0).looking_at(Vec3::ZERO, Vec3::Y), Transform::from_xyz(-2.0, 2.5, 5.0).looking_at(Vec3::ZERO, Vec3::Y),
EnvironmentMapLight {
intensity: 150.0,
..EnvironmentMapLight::solid_color(&mut images, Color::WHITE)
},
)); ));
// Light // Light

View File

@ -88,11 +88,6 @@ fn main() {
(handle_weight_drag, update_ui, sync_weights).chain(), (handle_weight_drag, update_ui, sync_weights).chain(),
) )
.insert_resource(args) .insert_resource(args)
.insert_resource(AmbientLight {
color: WHITE.into(),
brightness: 100.0,
..default()
})
.run(); .run();
} }
@ -216,11 +211,16 @@ fn setup_scene(
mut commands: Commands, mut commands: Commands,
asset_server: Res<AssetServer>, asset_server: Res<AssetServer>,
mut meshes: ResMut<Assets<Mesh>>, mut meshes: ResMut<Assets<Mesh>>,
mut images: ResMut<Assets<Image>>,
mut materials: ResMut<Assets<StandardMaterial>>, mut materials: ResMut<Assets<StandardMaterial>>,
) { ) {
commands.spawn(( commands.spawn((
Camera3d::default(), Camera3d::default(),
Transform::from_xyz(-10.0, 5.0, 13.0).looking_at(Vec3::new(0., 1., 0.), Vec3::Y), Transform::from_xyz(-10.0, 5.0, 13.0).looking_at(Vec3::new(0., 1., 0.), Vec3::Y),
EnvironmentMapLight {
intensity: 100.0,
..EnvironmentMapLight::solid_color(&mut images, Color::WHITE)
},
)); ));
commands.spawn(( commands.spawn((

View File

@ -2,7 +2,7 @@
use bevy::{ use bevy::{
animation::{AnimationTarget, AnimationTargetId}, animation::{AnimationTarget, AnimationTargetId},
color::palettes::css::{LIGHT_GRAY, WHITE}, color::palettes::css::LIGHT_GRAY,
prelude::*, prelude::*,
}; };
use std::collections::HashSet; use std::collections::HashSet;
@ -105,11 +105,6 @@ fn main() {
.add_systems(Update, setup_animation_graph_once_loaded) .add_systems(Update, setup_animation_graph_once_loaded)
.add_systems(Update, handle_button_toggles) .add_systems(Update, handle_button_toggles)
.add_systems(Update, update_ui) .add_systems(Update, update_ui)
.insert_resource(AmbientLight {
color: WHITE.into(),
brightness: 100.0,
..default()
})
.init_resource::<AppState>() .init_resource::<AppState>()
.run(); .run();
} }
@ -120,12 +115,17 @@ fn setup_scene(
mut commands: Commands, mut commands: Commands,
asset_server: Res<AssetServer>, asset_server: Res<AssetServer>,
mut meshes: ResMut<Assets<Mesh>>, mut meshes: ResMut<Assets<Mesh>>,
mut images: ResMut<Assets<Image>>,
mut materials: ResMut<Assets<StandardMaterial>>, mut materials: ResMut<Assets<StandardMaterial>>,
) { ) {
// Spawn the camera. // Spawn the camera.
commands.spawn(( commands.spawn((
Camera3d::default(), Camera3d::default(),
Transform::from_xyz(-15.0, 10.0, 20.0).looking_at(Vec3::new(0., 1., 0.), Vec3::Y), Transform::from_xyz(-15.0, 10.0, 20.0).looking_at(Vec3::new(0., 1., 0.), Vec3::Y),
EnvironmentMapLight {
intensity: 100.0,
..EnvironmentMapLight::solid_color(&mut images, Color::WHITE)
},
)); ));
// Spawn the light. // Spawn the light.

View File

@ -20,10 +20,6 @@ use rand_chacha::ChaCha8Rng;
fn main() { fn main() {
App::new() App::new()
.add_plugins(DefaultPlugins) .add_plugins(DefaultPlugins)
.insert_resource(AmbientLight {
brightness: 3000.0,
..default()
})
.add_systems(Startup, setup) .add_systems(Startup, setup)
.add_systems(Update, joint_animation) .add_systems(Update, joint_animation)
.run(); .run();
@ -40,6 +36,7 @@ fn setup(
mut commands: Commands, mut commands: Commands,
asset_server: Res<AssetServer>, asset_server: Res<AssetServer>,
mut meshes: ResMut<Assets<Mesh>>, mut meshes: ResMut<Assets<Mesh>>,
mut images: ResMut<Assets<Image>>,
mut materials: ResMut<Assets<StandardMaterial>>, mut materials: ResMut<Assets<StandardMaterial>>,
mut skinned_mesh_inverse_bindposes_assets: ResMut<Assets<SkinnedMeshInverseBindposes>>, mut skinned_mesh_inverse_bindposes_assets: ResMut<Assets<SkinnedMeshInverseBindposes>>,
) { ) {
@ -47,6 +44,10 @@ fn setup(
commands.spawn(( commands.spawn((
Camera3d::default(), Camera3d::default(),
Transform::from_xyz(2.5, 2.5, 9.0).looking_at(Vec3::ZERO, Vec3::Y), Transform::from_xyz(2.5, 2.5, 9.0).looking_at(Vec3::ZERO, Vec3::Y),
EnvironmentMapLight {
intensity: 3000.0,
..EnvironmentMapLight::solid_color(&mut images, Color::WHITE)
},
)); ));
// Create inverse bindpose matrices for a skeleton consists of 2 joints // Create inverse bindpose matrices for a skeleton consists of 2 joints

View File

@ -8,20 +8,24 @@ use bevy::{math::ops, prelude::*, render::mesh::skinning::SkinnedMesh};
fn main() { fn main() {
App::new() App::new()
.add_plugins(DefaultPlugins) .add_plugins(DefaultPlugins)
.insert_resource(AmbientLight {
brightness: 750.0,
..default()
})
.add_systems(Startup, setup) .add_systems(Startup, setup)
.add_systems(Update, joint_animation) .add_systems(Update, joint_animation)
.run(); .run();
} }
fn setup(mut commands: Commands, asset_server: Res<AssetServer>) { fn setup(
mut commands: Commands,
asset_server: Res<AssetServer>,
mut images: ResMut<Assets<Image>>,
) {
// Create a camera // Create a camera
commands.spawn(( commands.spawn((
Camera3d::default(), Camera3d::default(),
Transform::from_xyz(-2.0, 2.5, 5.0).looking_at(Vec3::new(0.0, 1.0, 0.0), Vec3::Y), Transform::from_xyz(-2.0, 2.5, 5.0).looking_at(Vec3::new(0.0, 1.0, 0.0), Vec3::Y),
EnvironmentMapLight {
intensity: 750.0,
..EnvironmentMapLight::solid_color(&mut images, Color::WHITE)
},
)); ));
// Spawn the first scene in `models/SimpleSkin/SimpleSkin.gltf` // Spawn the first scene in `models/SimpleSkin/SimpleSkin.gltf`

View File

@ -19,10 +19,6 @@ fn main() {
}), }),
..default() ..default()
})) }))
.insert_resource(AmbientLight {
brightness: 150.0,
..default()
})
.add_systems(Startup, setup) .add_systems(Startup, setup)
.add_systems(Update, (name_morphs, setup_animations)) .add_systems(Update, (name_morphs, setup_animations))
.run(); .run();
@ -34,7 +30,11 @@ struct MorphData {
mesh: Handle<Mesh>, mesh: Handle<Mesh>,
} }
fn setup(asset_server: Res<AssetServer>, mut commands: Commands) { fn setup(
asset_server: Res<AssetServer>,
mut commands: Commands,
mut images: ResMut<Assets<Image>>,
) {
commands.insert_resource(MorphData { commands.insert_resource(MorphData {
the_wave: asset_server the_wave: asset_server
.load(GltfAssetLabel::Animation(2).from_asset("models/animated/MorphStressTest.gltf")), .load(GltfAssetLabel::Animation(2).from_asset("models/animated/MorphStressTest.gltf")),
@ -56,6 +56,10 @@ fn setup(asset_server: Res<AssetServer>, mut commands: Commands) {
commands.spawn(( commands.spawn((
Camera3d::default(), Camera3d::default(),
Transform::from_xyz(3.0, 2.1, 10.2).looking_at(Vec3::ZERO, Vec3::Y), Transform::from_xyz(3.0, 2.1, 10.2).looking_at(Vec3::ZERO, Vec3::Y),
EnvironmentMapLight {
intensity: 150.0,
..EnvironmentMapLight::solid_color(&mut images, Color::WHITE)
},
)); ));
} }

View File

@ -17,11 +17,6 @@ fn main() {
App::new() App::new()
.add_plugins(DefaultPlugins) .add_plugins(DefaultPlugins)
.init_state::<LoadingState>() .init_state::<LoadingState>()
.insert_resource(AmbientLight {
color: Color::WHITE,
brightness: 2000.,
..default()
})
.add_systems(Startup, setup_assets) .add_systems(Startup, setup_assets)
.add_systems(Startup, setup_scene) .add_systems(Startup, setup_scene)
.add_systems(Startup, setup_ui) .add_systems(Startup, setup_ui)
@ -185,12 +180,17 @@ fn setup_ui(mut commands: Commands) {
fn setup_scene( fn setup_scene(
mut commands: Commands, mut commands: Commands,
mut meshes: ResMut<Assets<Mesh>>, mut meshes: ResMut<Assets<Mesh>>,
mut images: ResMut<Assets<Image>>,
mut materials: ResMut<Assets<StandardMaterial>>, mut materials: ResMut<Assets<StandardMaterial>>,
) { ) {
// Camera // Camera
commands.spawn(( commands.spawn((
Camera3d::default(), Camera3d::default(),
Transform::from_xyz(10.0, 10.0, 15.0).looking_at(Vec3::new(0.0, 0.0, 0.0), Vec3::Y), Transform::from_xyz(10.0, 10.0, 15.0).looking_at(Vec3::new(0.0, 0.0, 0.0), Vec3::Y),
EnvironmentMapLight {
intensity: 2000.0,
..EnvironmentMapLight::solid_color(&mut images, Color::WHITE)
},
)); ));
// Light // Light

View File

@ -14,7 +14,7 @@ fn main() {
.init_state::<CameraActive>(); .init_state::<CameraActive>();
// cameras // cameras
app.add_systems(Startup, (setup_cameras, setup_lights, setup_ambient_light)) app.add_systems(Startup, (setup_cameras, setup_lights))
.add_systems( .add_systems(
Update, Update,
( (
@ -292,14 +292,21 @@ const CIRCULAR_SEGMENT: CircularSegment = CircularSegment {
}, },
}; };
fn setup_cameras(mut commands: Commands) { fn setup_cameras(mut commands: Commands, mut images: ResMut<Assets<Image>>) {
let start_in_2d = true; let start_in_2d = true;
let make_camera = |is_active| Camera { let make_camera = |is_active| Camera {
is_active, is_active,
..Default::default() ..Default::default()
}; };
commands.spawn((Camera2d, make_camera(start_in_2d))); commands.spawn((
Camera2d,
make_camera(start_in_2d),
EnvironmentMapLight {
intensity: 50.0,
..EnvironmentMapLight::solid_color(&mut images, Color::WHITE)
},
));
commands.spawn(( commands.spawn((
Camera3d::default(), Camera3d::default(),
@ -308,10 +315,6 @@ fn setup_cameras(mut commands: Commands) {
)); ));
} }
fn setup_ambient_light(mut ambient_light: ResMut<AmbientLight>) {
ambient_light.brightness = 50.0;
}
fn setup_lights(mut commands: Commands) { fn setup_lights(mut commands: Commands) {
commands.spawn(( commands.spawn((
PointLight { PointLight {