1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
//! Lighting system for scene illumination.
//!
//! Provides light components following glTF KHR_lights_punctual:
//!
//! - [`Light`]: Light source component with type, color, and intensity
//! - [`LightType`]: Directional (sun), Point (omni), or Spot light
//!
//! Lights interact with the entity's transform to determine direction (directional/spot)
//! or position (point/spot). Shadow mapping is supported for all light types.
//!
//! # Quick Start: Add a Sun
//!
//! The easiest way to light a scene:
//!
//! ```ignore
//! spawn_sun(world); // Directional light with shadows
//! ```
//!
//! # Directional Light (Sun)
//!
//! Infinitely distant light affecting all objects uniformly:
//!
//! ```ignore
//! use nightshade::ecs::light::{Light, LightType};
//! use nightshade::ecs::world::LIGHT;
//!
//! let sun = world.spawn_entities(
//! LIGHT | LOCAL_TRANSFORM | GLOBAL_TRANSFORM | LOCAL_TRANSFORM_DIRTY,
//! 1
//! )[0];
//!
//! world.set_light(sun, Light {
//! light_type: LightType::Directional,
//! color: Vec3::new(1.0, 0.95, 0.9), // Warm white
//! intensity: 100000.0, // Lux (outdoor daylight ~100000)
//! cast_shadows: true,
//! shadow_bias: 0.005,
//! ..Default::default()
//! });
//!
//! // Light direction is entity's -Z axis
//! world.set_local_transform(sun, LocalTransform {
//! rotation: UnitQuaternion::from_euler_angles(-0.8, 0.5, 0.0),
//! ..Default::default()
//! });
//! world.add_local_transform_dirty(sun);
//! ```
//!
//! # Point Light (Omni)
//!
//! Light radiating in all directions from a position:
//!
//! ```ignore
//! let lamp = world.spawn_entities(
//! LIGHT | LOCAL_TRANSFORM | GLOBAL_TRANSFORM | LOCAL_TRANSFORM_DIRTY,
//! 1
//! )[0];
//!
//! world.set_light(lamp, Light {
//! light_type: LightType::Point,
//! color: Vec3::new(1.0, 0.8, 0.6), // Warm orange
//! intensity: 800.0, // Lumens (60W bulb ~800)
//! range: 10.0, // Falloff distance
//! cast_shadows: true,
//! shadow_bias: 0.001,
//! ..Default::default()
//! });
//!
//! world.set_local_transform(lamp, LocalTransform {
//! translation: Vec3::new(0.0, 3.0, 0.0),
//! ..Default::default()
//! });
//! world.add_local_transform_dirty(lamp);
//! ```
//!
//! # Spot Light
//!
//! Cone-shaped light for flashlights, stage lights, headlights:
//!
//! ```ignore
//! let spotlight = world.spawn_entities(
//! LIGHT | LOCAL_TRANSFORM | GLOBAL_TRANSFORM | LOCAL_TRANSFORM_DIRTY,
//! 1
//! )[0];
//!
//! world.set_light(spotlight, Light {
//! light_type: LightType::Spot,
//! color: Vec3::new(1.0, 1.0, 1.0),
//! intensity: 1000.0,
//! range: 20.0,
//! inner_cone_angle: 15.0_f32.to_radians(), // Full intensity cone
//! outer_cone_angle: 30.0_f32.to_radians(), // Falloff cone
//! cast_shadows: true,
//! shadow_bias: 0.002,
//! });
//!
//! // Position and aim the spotlight
//! world.set_local_transform(spotlight, LocalTransform {
//! translation: Vec3::new(5.0, 5.0, 0.0),
//! rotation: UnitQuaternion::face_towards(
//! &Vec3::new(-1.0, -1.0, 0.0), // Direction to target
//! &Vec3::y(),
//! ),
//! ..Default::default()
//! });
//! world.add_local_transform_dirty(spotlight);
//! ```
//!
//! # Light Properties
//!
//! | Property | Description |
//! |----------|-------------|
//! | `light_type` | Directional, Point, or Spot |
//! | `color` | Linear RGB color |
//! | `intensity` | Lumens (point/spot) or lux (directional) |
//! | `range` | Falloff distance for point/spot (0 = unlimited) |
//! | `inner_cone_angle` | Spot inner cone (full intensity) in radians |
//! | `outer_cone_angle` | Spot outer cone (zero intensity) in radians |
//! | `cast_shadows` | Enable shadow mapping |
//! | `shadow_bias` | Depth bias to reduce shadow acne |
//!
//! # Typical Intensity Values
//!
//! | Light Type | Intensity | Real-World Equivalent |
//! |------------|-----------|----------------------|
//! | Directional | 100000 lux | Bright daylight |
//! | Directional | 10000 lux | Overcast day |
//! | Point | 800 lumens | 60W incandescent bulb |
//! | Point | 1600 lumens | 100W bulb |
//! | Spot | 1000 lumens | Stage spotlight |
//!
//! # Disabling Shadows
//!
//! For performance or artistic reasons:
//!
//! ```ignore
//! // Light without shadows (no spawn_sun helper)
//! spawn_sun_without_shadows(world);
//!
//! // Or manually
//! light.cast_shadows = false;
//! ```
//!
//! [`Light`]: components::Light
//! [`LightType`]: components::LightType
pub use *;