DirectionalLight:平行光
平行光模拟距离极远的光源。太阳是典型的例子——从场景中看,所有光线近似平行,照射方向一致。
最小配置
DirectionalLight 是一个组件,挂在实体上。光照方向由实体的 Transform 的 forward(-Z)方向决定:
rust
use std::f32::consts::PI;
use bevy::prelude::*;
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_systems(Startup, setup)
.add_systems(Update, rotate_sun)
.run();
}
fn setup(
mut commands: Commands,
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<StandardMaterial>>,
) {
// 地面
commands.spawn((
Mesh3d(meshes.add(Plane3d::default().mesh().size(8.0, 8.0))),
MeshMaterial3d(materials.add(StandardMaterial {
base_color: Color::srgb(0.3, 0.3, 0.3),
perceptual_roughness: 1.0,
..default()
})),
));
// 展示物体——立方体、球体、圆环
commands.spawn((
Mesh3d(meshes.add(Cuboid::new(1.0, 1.0, 1.0))),
MeshMaterial3d(materials.add(StandardMaterial {
base_color: Color::srgb(0.8, 0.2, 0.2),
metallic: 0.5,
perceptual_roughness: 0.3,
..default()
})),
Transform::from_xyz(-1.5, 0.5, 0.0),
));
commands.spawn((
Mesh3d(meshes.add(Sphere::new(0.6).mesh().uv(32, 18))),
MeshMaterial3d(materials.add(StandardMaterial {
base_color: Color::srgb(0.2, 0.6, 0.8),
metallic: 0.9,
perceptual_roughness: 0.2,
..default()
})),
Transform::from_xyz(0.0, 0.6, 0.0),
));
commands.spawn((
Mesh3d(meshes.add(Torus::default())),
MeshMaterial3d(materials.add(StandardMaterial {
base_color: Color::srgb(0.9, 0.7, 0.1),
metallic: 0.8,
perceptual_roughness: 0.4,
..default()
})),
Transform::from_xyz(1.5, 0.5, 0.0),
));
// DirectionalLight:太阳
// 光照方向沿 Transform 的 forward(-Z),此处让光从斜上方照下
commands.spawn((
DirectionalLight {
illuminance: light_consts::lux::FULL_DAYLIGHT,
contact_shadows_enabled: true,
..default()
},
Transform::from_xyz(0.0, 5.0, 0.0)
.looking_at(Vec3::new(0.0, 0.0, -1.0), Vec3::Y),
));
// 相机
commands.spawn((
Camera3d::default(),
Transform::from_xyz(4.0, 3.0, 5.0).looking_at(Vec3::ZERO, Vec3::Y),
));
}
fn rotate_sun(time: Res<Time>, mut query: Query<&mut Transform, With<DirectionalLight>>) {
for mut transform in &mut query {
transform.rotate_y(time.delta_secs() * 0.2);
}
}Listing 22-1:DirectionalLight 最小配置——太阳绕 Y 轴旋转
illuminance 字段的单位是勒克斯(lux),表示单位面积上接收的光通量。light_consts::lux 模块提供了一组参考值:
| 值 | 对应场景 |
|---|---|
FULL_DAYLIGHT (10,000) | 晴天的直射阳光 |
OVERCAST_DAY (1,000) | 阴天 |
AMBIENT_DAYLIGHT (100) | 白天的环境光 |
contact_shadows_enabled: true 启用阴影投射。平行光的阴影实现基于级联阴影映射(CSM),由 CascadeShadowConfig 组件控制(见 22.5 节)。
方向由旋转决定
DirectionalLight 的位置字段不影响光照——平行光没有位置概念。只有旋转决定光线方向。代码中的 transform.looking_at(target, up) 是一种方便的朝向设定方式。
颜色与强度
color 字段设置光色,illuminance 决定强度:
rust
DirectionalLight {
color: Color::srgb(1.0, 0.95, 0.8), // 暖色日光
illuminance: light_consts::lux::FULL_DAYLIGHT,
..default()
}冷色光(偏蓝)模拟月光,暖色光(偏黄)模拟日出/日落。