1use wde_renderer::prelude::Color;
2
3use bevy::prelude::*;
4
5const DEFAULT_INTENSITY: f32 = 1.0;
7const INTENSITY_MULTIPLIER: f32 = 10.0; #[derive(Component, Clone, Copy, Reflect)]
11#[reflect(Component)]
12pub struct DirectionalLight {
13 pub direction: Vec3,
15
16 pub color: Color,
18 pub intensity: f32
20}
21impl Default for DirectionalLight {
22 fn default() -> Self {
23 Self {
24 direction: Vec3::new(0.0, -1.0, 0.0),
25 color: Color::from_srgba(1.0, 1.0, 1.0, 1.0),
26 intensity: DEFAULT_INTENSITY * INTENSITY_MULTIPLIER
27 }
28 }
29}
30
31#[derive(Component, Clone, Copy, Reflect)]
33#[reflect(Component)]
34pub struct PointLight {
35 pub position: Vec3,
37
38 pub color: Color,
40 pub intensity: f32,
42 pub range: f32
44}
45impl Default for PointLight {
46 fn default() -> Self {
47 Self {
48 position: Vec3::new(0.0, 0.0, 0.0),
49 color: Color::from_srgba(1.0, 1.0, 1.0, 1.0),
50 intensity: DEFAULT_INTENSITY * INTENSITY_MULTIPLIER,
51 range: 100.0
52 }
53 }
54}
55
56#[derive(Component, Clone, Copy, Reflect)]
58#[reflect(Component)]
59pub struct SpotLight {
60 pub position: Vec3,
62 pub direction: Vec3,
64
65 pub color: Color,
67 pub intensity: f32,
69 pub range: f32,
71
72 pub inner_cone: f32,
74 pub outer_cone: f32
76}
77impl Default for SpotLight {
78 fn default() -> Self {
79 Self {
80 position: Vec3::new(0.0, 0.0, 0.0),
81 direction: Vec3::new(0.0, -1.0, 0.0),
82 color: Color::from_srgba(1.0, 1.0, 1.0, 1.0),
83 intensity: DEFAULT_INTENSITY * INTENSITY_MULTIPLIER,
84 range: 50.0,
85 inner_cone: std::f32::consts::PI / 12.0, outer_cone: std::f32::consts::PI / 6.0 }
88 }
89}
90
91#[repr(C)]
93#[derive(Resource, Default, Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)]
94pub(crate) struct LightsStorageElement {
95 pub position_intensity: [f32; 4],
97 pub color_type: [f32; 4],
99 pub direction_range: [f32; 4],
101 pub spot_cone: [f32; 4]
103}
104impl LightsStorageElement {
105 pub fn end_marker() -> Self {
107 Self {
108 color_type: [0.0, 0.0, 0.0, -1.0],
109 ..Default::default()
110 }
111 }
112
113 pub fn from_directional(light: &DirectionalLight) -> Self {
114 let color = light.color.to_linear_rgba();
115 Self {
116 position_intensity: [0.0, 0.0, 0.0, light.intensity * INTENSITY_MULTIPLIER],
117 color_type: [color.r(), color.g(), color.b(), 0.0],
118 direction_range: [light.direction.x, light.direction.y, light.direction.z, 0.0],
119 spot_cone: [0.0, 0.0, 0.0, 0.0]
120 }
121 }
122
123 pub fn from_point(light: &PointLight) -> Self {
124 let color = light.color.to_linear_rgba();
125 Self {
126 position_intensity: [
127 light.position.x,
128 light.position.y,
129 light.position.z,
130 light.intensity * INTENSITY_MULTIPLIER
131 ],
132 color_type: [color.r(), color.g(), color.b(), 1.0],
133 direction_range: [0.0, 0.0, 0.0, light.range],
134 spot_cone: [0.0, 0.0, 0.0, 0.0]
135 }
136 }
137
138 pub fn from_spot(light: &SpotLight) -> Self {
139 let color = light.color.to_linear_rgba();
140 Self {
141 position_intensity: [
142 light.position.x,
143 light.position.y,
144 light.position.z,
145 light.intensity * INTENSITY_MULTIPLIER
146 ],
147 color_type: [color.r(), color.g(), color.b(), 2.0],
148 direction_range: [
149 light.direction.x,
150 light.direction.y,
151 light.direction.z,
152 light.range
153 ],
154 spot_cone: [light.inner_cone.cos(), light.outer_cone.cos(), 0.0, 0.0]
155 }
156 }
157}