Revert "Replace Ambient Lights with Environment Map Lights (#17482)" (#18167)

This reverts commit 0b5302d96a.

# Objective

- Fixes #18158
- #17482 introduced rendering changes and was merged a bit too fast

## Solution

- Revert #17482 so that it can be redone and rendering changes discussed
before being merged. This will make it easier to compare changes with
main in the known "valid" state

This is not an issue with the work done in #17482 that is still
interesting
This commit is contained in:
François Mockers 2025-03-06 00:08:46 +01:00 committed by GitHub
parent a530c07bc5
commit 54701a844e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
35 changed files with 212 additions and 348 deletions

View File

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

View File

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

View File

@ -20,13 +20,9 @@ use bevy_render::{
use bevy_transform::components::{GlobalTransform, Transform};
use bevy_utils::Parallel;
use crate::{prelude::EnvironmentMapLight, *};
use crate::*;
mod ambient_light;
#[expect(
deprecated,
reason = "AmbientLight has been replaced by EnvironmentMapLight"
)]
pub use ambient_light::AmbientLight;
mod point_light;
@ -513,7 +509,6 @@ pub struct LightVisibilityClass;
/// System sets used to run light-related systems.
#[derive(Debug, Hash, PartialEq, Eq, Clone, SystemSet)]
pub enum SimulationLightSystems {
MapAmbientLights,
AddClusters,
AssignLightsToClusters,
/// System order ambiguities between systems in this set are ignored:
@ -527,58 +522,6 @@ pub enum SimulationLightSystems {
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(
mut views: Query<
(

View File

@ -44,8 +44,7 @@
//!
//! [several pre-filtered environment maps]: https://github.com/KhronosGroup/glTF-Sample-Environments
use bevy_asset::{weak_handle, AssetId, Assets, Handle, RenderAssetUsages};
use bevy_color::{Color, ColorToPacked, Srgba};
use bevy_asset::{weak_handle, AssetId, Handle};
use bevy_ecs::{
component::Component, query::QueryItem, reflect::ReflectComponent, system::lifetimeless::Read,
};
@ -57,9 +56,8 @@ use bevy_render::{
render_asset::RenderAssets,
render_resource::{
binding_types::{self, uniform_buffer},
BindGroupLayoutEntryBuilder, Extent3d, Sampler, SamplerBindingType, Shader, ShaderStages,
TextureDimension, TextureFormat, TextureSampleType, TextureView, TextureViewDescriptor,
TextureViewDimension,
BindGroupLayoutEntryBuilder, Sampler, SamplerBindingType, Shader, ShaderStages,
TextureSampleType, TextureView,
},
renderer::{RenderAdapter, RenderDevice},
texture::{FallbackImage, GpuImage},
@ -116,83 +114,6 @@ pub struct EnvironmentMapLight {
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 {
fn default() -> Self {
EnvironmentMapLight {

View File

@ -139,6 +139,7 @@ bitflags::bitflags! {
#[derive(Copy, Clone, Debug, ShaderType)]
pub struct GpuLights {
directional_lights: [GpuDirectionalLight; MAX_DIRECTIONAL_LIGHTS],
ambient_color: Vec4,
// xyz are x/y/z cluster dimensions and w is the number of clusters
cluster_dimensions: UVec4,
// xy are vec2<f32>(cluster_dimensions.xy) / vec2<f32>(view.width, view.height)
@ -148,6 +149,7 @@ pub struct GpuLights {
n_directional_lights: u32,
// offset from spot light's light index to spot light's shadow map index
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
@ -727,9 +729,11 @@ pub fn prepare_lights(
&ExtractedClusterConfig,
Option<&RenderLayers>,
Has<NoIndirectDrawing>,
Option<&AmbientLight>,
),
With<Camera3d>,
>,
ambient_light: Res<AmbientLight>,
point_light_shadow_map: Res<PointLightShadowMap>,
directional_light_shadow_map: Res<DirectionalLightShadowMap>,
mut shadow_render_phases: ResMut<ViewBinnedRenderPhases<Shadow>>,
@ -1138,11 +1142,18 @@ pub fn prepare_lights(
let mut live_views = EntityHashSet::with_capacity(views_count);
// set up light data for each view
for (entity, camera_main_entity, extracted_view, clusters, maybe_layers, no_indirect_drawing) in
sorted_cameras
.0
.iter()
.filter_map(|sorted_camera| views.get(sorted_camera.entity).ok())
for (
entity,
camera_main_entity,
extracted_view,
clusters,
maybe_layers,
no_indirect_drawing,
maybe_ambient_override,
) in sorted_cameras
.0
.iter()
.filter_map(|sorted_camera| views.get(sorted_camera.entity).ok())
{
live_views.insert(entity);
@ -1164,8 +1175,11 @@ pub fn prepare_lights(
);
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 {
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(
clusters.dimensions.x as f32 / extracted_view.viewport.z as f32,
clusters.dimensions.y as f32 / extracted_view.viewport.w as f32,
@ -1180,6 +1194,8 @@ pub fn prepare_lights(
// 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
- 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

View File

@ -50,6 +50,7 @@ const DIRECTIONAL_LIGHT_FLAGS_AFFECTS_LIGHTMAPPED_MESH_DIFFUSE_BIT: u32 = 4u;
struct Lights {
// 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>,
ambient_color: vec4<f32>,
// x/y/z dimensions and n_clusters in w
cluster_dimensions: vec4<u32>,
// xy are vec2<f32>(cluster_dimensions.xy) / vec2<f32>(view.width, view.height)

View File

@ -0,0 +1,29 @@
#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,6 +561,18 @@ fn apply_pbr_lighting(
#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
// priority goes like this:
//
@ -632,6 +644,9 @@ fn apply_pbr_lighting(
#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
// light in the call to `specular_transmissive_light()` below
var specular_transmitted_environment_light = vec3<f32>(0.0);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -57,11 +57,7 @@ struct Cubemap {
image_handle: Handle<Image>,
}
fn setup(
mut commands: Commands,
asset_server: Res<AssetServer>,
mut images: ResMut<Assets<Image>>,
) {
fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
// directional 'sun' light
commands.spawn((
DirectionalLight {
@ -82,15 +78,17 @@ fn setup(
brightness: 1000.0,
..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 {
is_loaded: false,
index: 0,

View File

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

View File

@ -4,6 +4,10 @@ use bevy::prelude::*;
fn main() {
App::new()
.insert_resource(AmbientLight {
brightness: 60.0,
..default()
})
.add_plugins(DefaultPlugins)
.add_systems(Startup, setup)
.run();
@ -12,17 +16,12 @@ fn main() {
fn setup(
mut commands: Commands,
mut meshes: ResMut<Assets<Mesh>>,
mut images: ResMut<Assets<Image>>,
mut materials: ResMut<Assets<StandardMaterial>>,
) {
// camera
commands.spawn((
Camera3d::default(),
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

View File

@ -20,6 +20,10 @@ Rotate Camera: Left and Right Arrows";
fn main() {
App::new()
.insert_resource(AmbientLight {
brightness: 20.0,
..default()
})
.add_plugins(DefaultPlugins)
.add_systems(Startup, setup)
.add_systems(Update, (light_sway, movement, rotation))
@ -33,7 +37,6 @@ struct Movable;
fn setup(
mut commands: Commands,
mut meshes: ResMut<Assets<Mesh>>,
mut images: ResMut<Assets<Image>>,
mut materials: ResMut<Assets<StandardMaterial>>,
) {
// ground plane
@ -121,10 +124,6 @@ fn setup(
..default()
},
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((

View File

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

View File

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

View File

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

View File

@ -9,6 +9,11 @@ const GLTF_PATH: &str = "models/animated/Fox.glb";
fn main() {
App::new()
.insert_resource(AmbientLight {
color: Color::WHITE,
brightness: 2000.,
..default()
})
.add_plugins(DefaultPlugins)
.add_systems(Startup, setup_mesh_and_animation)
.add_systems(Startup, setup_camera_and_environment)
@ -93,17 +98,12 @@ fn play_animation_when_ready(
fn setup_camera_and_environment(
mut commands: Commands,
mut meshes: ResMut<Assets<Mesh>>,
mut images: ResMut<Assets<Image>>,
mut materials: ResMut<Assets<StandardMaterial>>,
) {
// Camera
commands.spawn((
Camera3d::default(),
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

View File

@ -8,6 +8,11 @@ const FOX_PATH: &str = "models/animated/Fox.glb";
fn main() {
App::new()
.insert_resource(AmbientLight {
color: Color::WHITE,
brightness: 2000.,
..default()
})
.add_plugins(DefaultPlugins)
.add_systems(Startup, setup)
.add_systems(Update, setup_scene_once_loaded)
@ -25,7 +30,6 @@ fn setup(
mut commands: Commands,
asset_server: Res<AssetServer>,
mut meshes: ResMut<Assets<Mesh>>,
mut images: ResMut<Assets<Image>>,
mut materials: ResMut<Assets<StandardMaterial>>,
mut graphs: ResMut<Assets<AnimationGraph>>,
) {
@ -48,10 +52,6 @@ fn setup(
commands.spawn((
Camera3d::default(),
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

View File

@ -13,6 +13,11 @@ const FOX_PATH: &str = "models/animated/Fox.glb";
fn main() {
App::new()
.insert_resource(AmbientLight {
color: Color::WHITE,
brightness: 2000.,
..default()
})
.add_plugins(DefaultPlugins)
.init_resource::<ParticleAssets>()
.init_resource::<FoxFeetTargets>()
@ -73,7 +78,6 @@ fn setup(
mut commands: Commands,
asset_server: Res<AssetServer>,
mut meshes: ResMut<Assets<Mesh>>,
mut images: ResMut<Assets<Image>>,
mut materials: ResMut<Assets<StandardMaterial>>,
mut graphs: ResMut<Assets<AnimationGraph>>,
) {
@ -94,10 +98,6 @@ fn setup(
commands.spawn((
Camera3d::default(),
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

View File

@ -10,6 +10,11 @@ use bevy::{
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.insert_resource(AmbientLight {
color: Color::WHITE,
brightness: 150.0,
..default()
})
.add_systems(Startup, setup)
.run();
}
@ -17,7 +22,6 @@ fn main() {
fn setup(
mut commands: Commands,
mut meshes: ResMut<Assets<Mesh>>,
mut images: ResMut<Assets<Image>>,
mut materials: ResMut<Assets<StandardMaterial>>,
mut animations: ResMut<Assets<AnimationClip>>,
mut graphs: ResMut<Assets<AnimationGraph>>,
@ -26,10 +30,6 @@ fn setup(
commands.spawn((
Camera3d::default(),
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

View File

@ -88,6 +88,11 @@ fn main() {
(handle_weight_drag, update_ui, sync_weights).chain(),
)
.insert_resource(args)
.insert_resource(AmbientLight {
color: WHITE.into(),
brightness: 100.0,
..default()
})
.run();
}
@ -211,16 +216,11 @@ fn setup_scene(
mut commands: Commands,
asset_server: Res<AssetServer>,
mut meshes: ResMut<Assets<Mesh>>,
mut images: ResMut<Assets<Image>>,
mut materials: ResMut<Assets<StandardMaterial>>,
) {
commands.spawn((
Camera3d::default(),
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((

View File

@ -2,7 +2,7 @@
use bevy::{
animation::{AnimationTarget, AnimationTargetId},
color::palettes::css::LIGHT_GRAY,
color::palettes::css::{LIGHT_GRAY, WHITE},
prelude::*,
};
use std::collections::HashSet;
@ -105,6 +105,11 @@ fn main() {
.add_systems(Update, setup_animation_graph_once_loaded)
.add_systems(Update, handle_button_toggles)
.add_systems(Update, update_ui)
.insert_resource(AmbientLight {
color: WHITE.into(),
brightness: 100.0,
..default()
})
.init_resource::<AppState>()
.run();
}
@ -115,17 +120,12 @@ fn setup_scene(
mut commands: Commands,
asset_server: Res<AssetServer>,
mut meshes: ResMut<Assets<Mesh>>,
mut images: ResMut<Assets<Image>>,
mut materials: ResMut<Assets<StandardMaterial>>,
) {
// Spawn the camera.
commands.spawn((
Camera3d::default(),
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.

View File

@ -20,6 +20,10 @@ use rand_chacha::ChaCha8Rng;
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.insert_resource(AmbientLight {
brightness: 3000.0,
..default()
})
.add_systems(Startup, setup)
.add_systems(Update, joint_animation)
.run();
@ -36,7 +40,6 @@ fn setup(
mut commands: Commands,
asset_server: Res<AssetServer>,
mut meshes: ResMut<Assets<Mesh>>,
mut images: ResMut<Assets<Image>>,
mut materials: ResMut<Assets<StandardMaterial>>,
mut skinned_mesh_inverse_bindposes_assets: ResMut<Assets<SkinnedMeshInverseBindposes>>,
) {
@ -44,10 +47,6 @@ fn setup(
commands.spawn((
Camera3d::default(),
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

View File

@ -8,24 +8,20 @@ use bevy::{math::ops, prelude::*, render::mesh::skinning::SkinnedMesh};
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.insert_resource(AmbientLight {
brightness: 750.0,
..default()
})
.add_systems(Startup, setup)
.add_systems(Update, joint_animation)
.run();
}
fn setup(
mut commands: Commands,
asset_server: Res<AssetServer>,
mut images: ResMut<Assets<Image>>,
) {
fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
// Create a camera
commands.spawn((
Camera3d::default(),
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`

View File

@ -19,6 +19,10 @@ fn main() {
}),
..default()
}))
.insert_resource(AmbientLight {
brightness: 150.0,
..default()
})
.add_systems(Startup, setup)
.add_systems(Update, (name_morphs, setup_animations))
.run();
@ -30,11 +34,7 @@ struct MorphData {
mesh: Handle<Mesh>,
}
fn setup(
asset_server: Res<AssetServer>,
mut commands: Commands,
mut images: ResMut<Assets<Image>>,
) {
fn setup(asset_server: Res<AssetServer>, mut commands: Commands) {
commands.insert_resource(MorphData {
the_wave: asset_server
.load(GltfAssetLabel::Animation(2).from_asset("models/animated/MorphStressTest.gltf")),
@ -56,10 +56,6 @@ fn setup(
commands.spawn((
Camera3d::default(),
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,6 +17,11 @@ fn main() {
App::new()
.add_plugins(DefaultPlugins)
.init_state::<LoadingState>()
.insert_resource(AmbientLight {
color: Color::WHITE,
brightness: 2000.,
..default()
})
.add_systems(Startup, setup_assets)
.add_systems(Startup, setup_scene)
.add_systems(Startup, setup_ui)
@ -180,17 +185,12 @@ fn setup_ui(mut commands: Commands) {
fn setup_scene(
mut commands: Commands,
mut meshes: ResMut<Assets<Mesh>>,
mut images: ResMut<Assets<Image>>,
mut materials: ResMut<Assets<StandardMaterial>>,
) {
// Camera
commands.spawn((
Camera3d::default(),
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

View File

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