ambient lighting fix
Guide for ambient lighting fix
Ambient Lighting Fix for Black Screen
Problem
After implementing player spawning and UI visibility fixes, the user reported seeing a black screen when entering the game (Tutorial or Playing state). The UI was visible, but the 3D world appeared completely black.
Root Cause
The world setup only included a directional light (sun), which may not provide sufficient illumination for all objects in the scene, especially if:
- Objects are in shadow from the directional light
- The camera angle doesn't receive direct light
- Materials have low reflectivity
File:
src/systems/world/mod.rs (lines 58-68)Original Implementation:
fn setup_world(
mut commands: Commands,
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<StandardMaterial>>,
) {
// Ground Plane
commands.spawn((
PbrBundle {
mesh: meshes.add(Plane3d::default().mesh().size(200.0, 200.0)),
material: materials.add(StandardMaterial {
base_color: Color::srgb(0.3, 0.5, 0.3), // Grass Green
perceptual_roughness: 1.0,
..default()
}),
transform: Transform::from_xyz(0.0, 0.0, 0.0),
..default()
},
Name::new("Ground"),
avian3d::prelude::Collider::cuboid(200.0, 0.1, 200.0),
avian3d::prelude::RigidBody::Static,
));
// Directional Light (Sun)
commands.spawn(DirectionalLightBundle {
directional_light: DirectionalLight {
shadows_enabled: true,
illuminance: 10000.0,
..default()
},
transform: Transform::from_xyz(50.0, 100.0, 50.0).looking_at(Vec3::ZERO, Vec3::Y),
..default()
});
}Issue: Only directional light exists, which creates harsh shadows and may leave areas completely dark.
Solution
Add
AmbientLight resource to provide global illumination that ensures all objects have a minimum level of visibility.Implementation
File:
src/systems/world/mod.rs (lines 58-75)Updated Code:
fn setup_world(
mut commands: Commands,
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<StandardMaterial>>,
) {
// Ground Plane
commands.spawn((
PbrBundle {
mesh: meshes.add(Plane3d::default().mesh().size(200.0, 200.0)),
material: materials.add(StandardMaterial {
base_color: Color::srgb(0.3, 0.5, 0.3), // Grass Green
perceptual_roughness: 1.0,
..default()
}),
transform: Transform::from_xyz(0.0, 0.0, 0.0),
..default()
},
Name::new("Ground"),
avian3d::prelude::Collider::cuboid(200.0, 0.1, 200.0),
avian3d::prelude::RigidBody::Static,
));
// Directional Light (Sun)
commands.spawn(DirectionalLightBundle {
directional_light: DirectionalLight {
shadows_enabled: true,
illuminance: 10000.0,
..default()
},
transform: Transform::from_xyz(50.0, 100.0, 50.0).looking_at(Vec3::ZERO, Vec3::Y),
..default()
});
// [FIX] Add Ambient Light to ensure visibility
commands.insert_resource(AmbientLight {
color: Color::WHITE,
brightness: 500.0,
});
info!("World Environment (Ground + Lights) Setup Complete");
}Changes:
- Added
AmbientLightresource with white color and brightness of 500.0 - Added info log to confirm world setup completion
Why This Works
Bevy Lighting System
Bevy's PBR (Physically Based Rendering) system supports multiple light types:
- Directional Light: Simulates sunlight, provides strong directional illumination
- Point Light: Omnidirectional light from a point source
- Spot Light: Cone-shaped light
- Ambient Light: Global illumination that affects all objects equally
Ambient Light provides a baseline level of illumination that ensures:
- No object is completely black (even in shadow)
- Materials are visible regardless of camera angle
- The scene has a minimum level of brightness
Brightness Value
The brightness value of
500.0 was chosen to:- Provide sufficient base illumination without washing out the scene
- Allow the directional light to still create visible shadows and depth
- Ensure the ground plane and player are clearly visible
Typical values:
100.0-300.0: Subtle ambient lighting (indoor scenes)500.0-800.0: Moderate ambient lighting (outdoor daytime)1000.0+: Strong ambient lighting (may reduce shadow contrast)
Verification
After applying the fix:
cargo run --bin legends_clientVerification Logs:
2026-01-05T15:18:45.123998Z INFO ThreadId(18) World Environment (Ground + Lights) Setup Complete
2026-01-05T15:18:45.182538Z WARN ThreadId(01) Entity { index: 9, generation: 1 } (Ground) and Entity { index: 14, generation: 1 } are overlapping at spawnConfirmed:
- ✅ World setup executes successfully
- ✅ Ground entity spawns (Entity index 9)
- ✅ Ambient light resource is added
- ✅ Scene should now be visible (not black)
Related Patterns
Lighting Best Practices for Bevy
Outdoor Scenes:
// Strong directional light (sun)
commands.spawn(DirectionalLightBundle {
directional_light: DirectionalLight {
illuminance: 10000.0,
shadows_enabled: true,
..default()
},
transform: Transform::from_xyz(50.0, 100.0, 50.0).looking_at(Vec3::ZERO, Vec3::Y),
..default()
});
// Moderate ambient light (sky)
commands.insert_resource(AmbientLight {
color: Color::srgb(0.8, 0.9, 1.0), // Slight blue tint for sky
brightness: 500.0,
});Indoor Scenes:
// Weaker directional light (window)
commands.spawn(DirectionalLightBundle {
directional_light: DirectionalLight {
illuminance: 3000.0,
shadows_enabled: true,
..default()
},
// ...
});
// Subtle ambient light
commands.insert_resource(AmbientLight {
color: Color::WHITE,
brightness: 200.0,
});
// Add point lights for lamps/torches
commands.spawn(PointLightBundle {
point_light: PointLight {
intensity: 1500.0,
range: 20.0,
..default()
},
transform: Transform::from_xyz(0.0, 2.0, 0.0),
..default()
});Dynamic Lighting
For day/night cycles or dynamic scenes:
fn update_ambient_light(
mut ambient: ResMut<AmbientLight>,
time: Res<Time>,
) {
// Simulate day/night cycle
let time_of_day = (time.elapsed_seconds() / 60.0) % 24.0; // 1 minute = 1 hour
let brightness = if time_of_day < 6.0 || time_of_day > 20.0 {
100.0 // Night
} else if time_of_day < 8.0 || time_of_day > 18.0 {
300.0 // Dawn/Dusk
} else {
500.0 // Day
};
ambient.brightness = brightness;
}Files Modified
src/systems/world/mod.rs(lines 68-75): AddedAmbientLightresource and logging
Related Knowledge
- hud_state_management_extended.md: UI visibility fixes that revealed the black screen issue
- loh_player_spawning_system: Player spawning implementation that enabled entering the game world