1
1
use crate :: {
2
- light:: { AmbientLight , PointLight , PointLightUniform } ,
2
+ light:: {
3
+ AmbientLight , DirectionalLight , DirectionalLightUniform , PointLight , PointLightUniform ,
4
+ } ,
3
5
render_graph:: uniform,
4
6
} ;
5
7
use bevy_core:: { AsBytes , Byteable } ;
@@ -21,12 +23,14 @@ use bevy_transform::prelude::*;
21
23
pub struct LightsNode {
22
24
command_queue : CommandQueue ,
23
25
max_point_lights : usize ,
26
+ max_dir_lights : usize ,
24
27
}
25
28
26
29
impl LightsNode {
27
- pub fn new ( max_lights : usize ) -> Self {
30
+ pub fn new ( max_point_lights : usize , max_dir_lights : usize ) -> Self {
28
31
LightsNode {
29
- max_point_lights : max_lights,
32
+ max_point_lights,
33
+ max_dir_lights,
30
34
command_queue : CommandQueue :: default ( ) ,
31
35
}
32
36
}
@@ -48,6 +52,8 @@ impl Node for LightsNode {
48
52
#[ derive( Debug , Clone , Copy ) ]
49
53
struct LightCount {
50
54
// storing as a `[u32; 4]` for memory alignement
55
+ // Index 0 is for point lights,
56
+ // Index 1 is for directional lights
51
57
pub num_lights : [ u32 ; 4 ] ,
52
58
}
53
59
@@ -59,6 +65,7 @@ impl SystemNode for LightsNode {
59
65
config. 0 = Some ( LightsNodeSystemState {
60
66
command_queue : self . command_queue . clone ( ) ,
61
67
max_point_lights : self . max_point_lights ,
68
+ max_dir_lights : self . max_dir_lights ,
62
69
light_buffer : None ,
63
70
staging_buffer : None ,
64
71
} )
@@ -74,6 +81,7 @@ pub struct LightsNodeSystemState {
74
81
staging_buffer : Option < BufferId > ,
75
82
command_queue : CommandQueue ,
76
83
max_point_lights : usize ,
84
+ max_dir_lights : usize ,
77
85
}
78
86
79
87
pub fn lights_node_system (
@@ -83,7 +91,8 @@ pub fn lights_node_system(
83
91
// TODO: this write on RenderResourceBindings will prevent this system from running in parallel
84
92
// with other systems that do the same
85
93
mut render_resource_bindings : ResMut < RenderResourceBindings > ,
86
- query : Query < ( & PointLight , & GlobalTransform ) > ,
94
+ point_lights : Query < ( & PointLight , & GlobalTransform ) > ,
95
+ dir_lights : Query < & DirectionalLight > ,
87
96
) {
88
97
let state = & mut state;
89
98
let render_resource_context = & * * render_resource_context;
@@ -92,16 +101,31 @@ pub fn lights_node_system(
92
101
let ambient_light: [ f32 ; 4 ] =
93
102
( ambient_light_resource. color * ambient_light_resource. brightness ) . into ( ) ;
94
103
let ambient_light_size = std:: mem:: size_of :: < [ f32 ; 4 ] > ( ) ;
95
- let point_light_count = query. iter ( ) . len ( ) . min ( state. max_point_lights ) ;
96
- let size = std:: mem:: size_of :: < PointLightUniform > ( ) ;
104
+
105
+ let point_light_count = point_lights. iter ( ) . len ( ) . min ( state. max_point_lights ) ;
106
+ let point_light_size = std:: mem:: size_of :: < PointLightUniform > ( ) ;
107
+ let point_light_array_size = point_light_size * point_light_count;
108
+ let point_light_array_max_size = point_light_size * state. max_point_lights ;
109
+
110
+ let dir_light_count = dir_lights. iter ( ) . len ( ) . min ( state. max_dir_lights ) ;
111
+ let dir_light_size = std:: mem:: size_of :: < DirectionalLightUniform > ( ) ;
112
+ let dir_light_array_size = dir_light_size * dir_light_count;
113
+ let dir_light_array_max_size = dir_light_size * state. max_dir_lights ;
114
+
97
115
let light_count_size = ambient_light_size + std:: mem:: size_of :: < LightCount > ( ) ;
98
- let point_light_array_size = size * point_light_count;
99
- let point_light_array_max_size = size * state. max_point_lights ;
100
- let current_point_light_uniform_size = light_count_size + point_light_array_size;
101
- let max_light_uniform_size = light_count_size + point_light_array_max_size;
116
+
117
+ let point_light_uniform_start = light_count_size;
118
+ let point_light_uniform_end = light_count_size + point_light_array_size;
119
+
120
+ let dir_light_uniform_start = light_count_size + point_light_array_max_size;
121
+ let dir_light_uniform_end =
122
+ light_count_size + point_light_array_max_size + dir_light_array_size;
123
+
124
+ let max_light_uniform_size =
125
+ light_count_size + point_light_array_max_size + dir_light_array_max_size;
102
126
103
127
if let Some ( staging_buffer) = state. staging_buffer {
104
- if point_light_count == 0 {
128
+ if point_light_count == 0 && dir_light_count == 0 {
105
129
return ;
106
130
}
107
131
@@ -133,23 +157,33 @@ pub fn lights_node_system(
133
157
let staging_buffer = state. staging_buffer . unwrap ( ) ;
134
158
render_resource_context. write_mapped_buffer (
135
159
staging_buffer,
136
- 0 ..current_point_light_uniform_size as u64 ,
160
+ 0 ..max_light_uniform_size as u64 ,
137
161
& mut |data, _renderer| {
138
162
// ambient light
139
163
data[ 0 ..ambient_light_size] . copy_from_slice ( ambient_light. as_bytes ( ) ) ;
140
164
141
165
// light count
142
- data[ ambient_light_size..light_count_size]
143
- . copy_from_slice ( [ point_light_count as u32 , 0 , 0 , 0 ] . as_bytes ( ) ) ;
166
+ data[ ambient_light_size..light_count_size] . copy_from_slice (
167
+ [ point_light_count as u32 , dir_light_count as u32 , 0 , 0 ] . as_bytes ( ) ,
168
+ ) ;
144
169
145
- // light array
146
- for ( ( point_light, global_transform) , slot) in query. iter ( ) . zip (
147
- data[ light_count_size..current_point_light_uniform_size] . chunks_exact_mut ( size) ,
170
+ // point light array
171
+ for ( ( point_light, global_transform) , slot) in point_lights. iter ( ) . zip (
172
+ data[ point_light_uniform_start..point_light_uniform_end]
173
+ . chunks_exact_mut ( point_light_size) ,
148
174
) {
149
175
slot. copy_from_slice (
150
- PointLightUniform :: from ( & point_light, & global_transform) . as_bytes ( ) ,
176
+ PointLightUniform :: new ( & point_light, & global_transform) . as_bytes ( ) ,
151
177
) ;
152
178
}
179
+
180
+ // directional light array
181
+ for ( dir_light, slot) in dir_lights. iter ( ) . zip (
182
+ data[ dir_light_uniform_start..dir_light_uniform_end]
183
+ . chunks_exact_mut ( dir_light_size) ,
184
+ ) {
185
+ slot. copy_from_slice ( DirectionalLightUniform :: new ( & dir_light) . as_bytes ( ) ) ;
186
+ }
153
187
} ,
154
188
) ;
155
189
render_resource_context. unmap_buffer ( staging_buffer) ;
0 commit comments