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 from_directional(light: &DirectionalLight) -> Self {
106 let color = light.color.to_linear_rgba();
107 Self {
108 position_intensity: [0.0, 0.0, 0.0, light.intensity * INTENSITY_MULTIPLIER],
109 color_type: [color.r(), color.g(), color.b(), 0.0],
110 direction_range: [light.direction.x, light.direction.y, light.direction.z, 0.0],
111 spot_cone: [0.0, 0.0, 0.0, 0.0]
112 }
113 }
114
115 pub fn from_point(light: &PointLight) -> Self {
116 let color = light.color.to_linear_rgba();
117 Self {
118 position_intensity: [
119 light.position.x,
120 light.position.y,
121 light.position.z,
122 light.intensity * INTENSITY_MULTIPLIER
123 ],
124 color_type: [color.r(), color.g(), color.b(), 1.0],
125 direction_range: [0.0, 0.0, 0.0, light.range],
126 spot_cone: [0.0, 0.0, 0.0, 0.0]
127 }
128 }
129
130 pub fn from_spot(light: &SpotLight) -> Self {
131 let color = light.color.to_linear_rgba();
132 Self {
133 position_intensity: [
134 light.position.x,
135 light.position.y,
136 light.position.z,
137 light.intensity * INTENSITY_MULTIPLIER
138 ],
139 color_type: [color.r(), color.g(), color.b(), 2.0],
140 direction_range: [
141 light.direction.x,
142 light.direction.y,
143 light.direction.z,
144 light.range
145 ],
146 spot_cone: [light.inner_cone.cos(), light.outer_cone.cos(), 0.0, 0.0]
147 }
148 }
149}