1/**************************************************************************/
2/* light_storage.cpp */
3/**************************************************************************/
4/* This file is part of: */
5/* GODOT ENGINE */
6/* https://godotengine.org */
7/**************************************************************************/
8/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
9/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
10/* */
11/* Permission is hereby granted, free of charge, to any person obtaining */
12/* a copy of this software and associated documentation files (the */
13/* "Software"), to deal in the Software without restriction, including */
14/* without limitation the rights to use, copy, modify, merge, publish, */
15/* distribute, sublicense, and/or sell copies of the Software, and to */
16/* permit persons to whom the Software is furnished to do so, subject to */
17/* the following conditions: */
18/* */
19/* The above copyright notice and this permission notice shall be */
20/* included in all copies or substantial portions of the Software. */
21/* */
22/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
25/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29/**************************************************************************/
30
31#include "light_storage.h"
32#include "core/config/project_settings.h"
33#include "servers/rendering/renderer_rd/renderer_scene_render_rd.h"
34#include "texture_storage.h"
35
36using namespace RendererRD;
37
38LightStorage *LightStorage::singleton = nullptr;
39
40LightStorage *LightStorage::get_singleton() {
41 return singleton;
42}
43
44LightStorage::LightStorage() {
45 singleton = this;
46
47 TextureStorage *texture_storage = TextureStorage::get_singleton();
48
49 directional_shadow.size = GLOBAL_GET("rendering/lights_and_shadows/directional_shadow/size");
50 directional_shadow.use_16_bits = GLOBAL_GET("rendering/lights_and_shadows/directional_shadow/16_bits");
51
52 using_lightmap_array = true; // high end
53 if (using_lightmap_array) {
54 uint64_t textures_per_stage = RD::get_singleton()->limit_get(RD::LIMIT_MAX_TEXTURES_PER_SHADER_STAGE);
55
56 if (textures_per_stage <= 256) {
57 lightmap_textures.resize(32);
58 } else {
59 lightmap_textures.resize(1024);
60 }
61
62 for (int i = 0; i < lightmap_textures.size(); i++) {
63 lightmap_textures.write[i] = texture_storage->texture_rd_get_default(TextureStorage::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE);
64 }
65 }
66
67 lightmap_probe_capture_update_speed = GLOBAL_GET("rendering/lightmapping/probe_capture/update_speed");
68}
69
70LightStorage::~LightStorage() {
71 free_reflection_data();
72 free_light_data();
73
74 for (const KeyValue<int, ShadowCubemap> &E : shadow_cubemaps) {
75 RD::get_singleton()->free(E.value.cubemap);
76 }
77
78 singleton = nullptr;
79}
80
81bool LightStorage::free(RID p_rid) {
82 if (owns_reflection_probe(p_rid)) {
83 reflection_probe_free(p_rid);
84 return true;
85 } else if (owns_reflection_atlas(p_rid)) {
86 reflection_atlas_free(p_rid);
87 return true;
88 } else if (owns_reflection_probe_instance(p_rid)) {
89 reflection_probe_instance_free(p_rid);
90 return true;
91 } else if (owns_light(p_rid)) {
92 light_free(p_rid);
93 return true;
94 } else if (owns_light_instance(p_rid)) {
95 light_instance_free(p_rid);
96 return true;
97 } else if (owns_lightmap(p_rid)) {
98 lightmap_free(p_rid);
99 return true;
100 } else if (owns_lightmap_instance(p_rid)) {
101 lightmap_instance_free(p_rid);
102 return true;
103 } else if (owns_shadow_atlas(p_rid)) {
104 shadow_atlas_free(p_rid);
105 return true;
106 }
107
108 return false;
109}
110
111/* LIGHT */
112
113void LightStorage::_light_initialize(RID p_light, RS::LightType p_type) {
114 Light light;
115 light.type = p_type;
116
117 light.param[RS::LIGHT_PARAM_ENERGY] = 1.0;
118 light.param[RS::LIGHT_PARAM_INDIRECT_ENERGY] = 1.0;
119 light.param[RS::LIGHT_PARAM_VOLUMETRIC_FOG_ENERGY] = 1.0;
120 light.param[RS::LIGHT_PARAM_SPECULAR] = 0.5;
121 light.param[RS::LIGHT_PARAM_RANGE] = 1.0;
122 light.param[RS::LIGHT_PARAM_SIZE] = 0.0;
123 light.param[RS::LIGHT_PARAM_ATTENUATION] = 1.0;
124 light.param[RS::LIGHT_PARAM_SPOT_ANGLE] = 45;
125 light.param[RS::LIGHT_PARAM_SPOT_ATTENUATION] = 1.0;
126 light.param[RS::LIGHT_PARAM_SHADOW_MAX_DISTANCE] = 0;
127 light.param[RS::LIGHT_PARAM_SHADOW_SPLIT_1_OFFSET] = 0.1;
128 light.param[RS::LIGHT_PARAM_SHADOW_SPLIT_2_OFFSET] = 0.3;
129 light.param[RS::LIGHT_PARAM_SHADOW_SPLIT_3_OFFSET] = 0.6;
130 light.param[RS::LIGHT_PARAM_SHADOW_FADE_START] = 0.8;
131 light.param[RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS] = 1.0;
132 light.param[RS::LIGHT_PARAM_SHADOW_BIAS] = 0.02;
133 light.param[RS::LIGHT_PARAM_SHADOW_OPACITY] = 1.0;
134 light.param[RS::LIGHT_PARAM_SHADOW_BLUR] = 0;
135 light.param[RS::LIGHT_PARAM_SHADOW_PANCAKE_SIZE] = 20.0;
136 light.param[RS::LIGHT_PARAM_TRANSMITTANCE_BIAS] = 0.05;
137 light.param[RS::LIGHT_PARAM_INTENSITY] = p_type == RS::LIGHT_DIRECTIONAL ? 100000.0 : 1000.0;
138
139 light_owner.initialize_rid(p_light, light);
140}
141
142RID LightStorage::directional_light_allocate() {
143 return light_owner.allocate_rid();
144}
145
146void LightStorage::directional_light_initialize(RID p_light) {
147 _light_initialize(p_light, RS::LIGHT_DIRECTIONAL);
148}
149
150RID LightStorage::omni_light_allocate() {
151 return light_owner.allocate_rid();
152}
153
154void LightStorage::omni_light_initialize(RID p_light) {
155 _light_initialize(p_light, RS::LIGHT_OMNI);
156}
157
158RID LightStorage::spot_light_allocate() {
159 return light_owner.allocate_rid();
160}
161
162void LightStorage::spot_light_initialize(RID p_light) {
163 _light_initialize(p_light, RS::LIGHT_SPOT);
164}
165
166void LightStorage::light_free(RID p_rid) {
167 light_set_projector(p_rid, RID()); //clear projector
168
169 // delete the texture
170 Light *light = light_owner.get_or_null(p_rid);
171 light->dependency.deleted_notify(p_rid);
172 light_owner.free(p_rid);
173}
174
175void LightStorage::light_set_color(RID p_light, const Color &p_color) {
176 Light *light = light_owner.get_or_null(p_light);
177 ERR_FAIL_COND(!light);
178
179 light->color = p_color;
180}
181
182void LightStorage::light_set_param(RID p_light, RS::LightParam p_param, float p_value) {
183 Light *light = light_owner.get_or_null(p_light);
184 ERR_FAIL_COND(!light);
185 ERR_FAIL_INDEX(p_param, RS::LIGHT_PARAM_MAX);
186
187 if (light->param[p_param] == p_value) {
188 return;
189 }
190
191 switch (p_param) {
192 case RS::LIGHT_PARAM_RANGE:
193 case RS::LIGHT_PARAM_SPOT_ANGLE:
194 case RS::LIGHT_PARAM_SHADOW_MAX_DISTANCE:
195 case RS::LIGHT_PARAM_SHADOW_SPLIT_1_OFFSET:
196 case RS::LIGHT_PARAM_SHADOW_SPLIT_2_OFFSET:
197 case RS::LIGHT_PARAM_SHADOW_SPLIT_3_OFFSET:
198 case RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS:
199 case RS::LIGHT_PARAM_SHADOW_PANCAKE_SIZE:
200 case RS::LIGHT_PARAM_SHADOW_BIAS: {
201 light->version++;
202 light->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_LIGHT);
203 } break;
204 case RS::LIGHT_PARAM_SIZE: {
205 if ((light->param[p_param] > CMP_EPSILON) != (p_value > CMP_EPSILON)) {
206 //changing from no size to size and the opposite
207 light->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_LIGHT_SOFT_SHADOW_AND_PROJECTOR);
208 }
209 } break;
210 default: {
211 }
212 }
213
214 light->param[p_param] = p_value;
215}
216
217void LightStorage::light_set_shadow(RID p_light, bool p_enabled) {
218 Light *light = light_owner.get_or_null(p_light);
219 ERR_FAIL_COND(!light);
220 light->shadow = p_enabled;
221
222 light->version++;
223 light->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_LIGHT);
224}
225
226void LightStorage::light_set_projector(RID p_light, RID p_texture) {
227 TextureStorage *texture_storage = TextureStorage::get_singleton();
228 Light *light = light_owner.get_or_null(p_light);
229 ERR_FAIL_COND(!light);
230
231 if (light->projector == p_texture) {
232 return;
233 }
234
235 ERR_FAIL_COND(p_texture.is_valid() && !texture_storage->owns_texture(p_texture));
236
237 if (light->type != RS::LIGHT_DIRECTIONAL && light->projector.is_valid()) {
238 texture_storage->texture_remove_from_decal_atlas(light->projector, light->type == RS::LIGHT_OMNI);
239 }
240
241 light->projector = p_texture;
242
243 if (light->type != RS::LIGHT_DIRECTIONAL) {
244 if (light->projector.is_valid()) {
245 texture_storage->texture_add_to_decal_atlas(light->projector, light->type == RS::LIGHT_OMNI);
246 }
247 light->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_LIGHT_SOFT_SHADOW_AND_PROJECTOR);
248 }
249}
250
251void LightStorage::light_set_negative(RID p_light, bool p_enable) {
252 Light *light = light_owner.get_or_null(p_light);
253 ERR_FAIL_COND(!light);
254
255 light->negative = p_enable;
256}
257
258void LightStorage::light_set_cull_mask(RID p_light, uint32_t p_mask) {
259 Light *light = light_owner.get_or_null(p_light);
260 ERR_FAIL_COND(!light);
261
262 light->cull_mask = p_mask;
263
264 light->version++;
265 light->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_LIGHT);
266}
267
268void LightStorage::light_set_distance_fade(RID p_light, bool p_enabled, float p_begin, float p_shadow, float p_length) {
269 Light *light = light_owner.get_or_null(p_light);
270 ERR_FAIL_COND(!light);
271
272 light->distance_fade = p_enabled;
273 light->distance_fade_begin = p_begin;
274 light->distance_fade_shadow = p_shadow;
275 light->distance_fade_length = p_length;
276}
277
278void LightStorage::light_set_reverse_cull_face_mode(RID p_light, bool p_enabled) {
279 Light *light = light_owner.get_or_null(p_light);
280 ERR_FAIL_COND(!light);
281
282 light->reverse_cull = p_enabled;
283
284 light->version++;
285 light->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_LIGHT);
286}
287
288void LightStorage::light_set_bake_mode(RID p_light, RS::LightBakeMode p_bake_mode) {
289 Light *light = light_owner.get_or_null(p_light);
290 ERR_FAIL_COND(!light);
291
292 light->bake_mode = p_bake_mode;
293
294 light->version++;
295 light->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_LIGHT);
296}
297
298void LightStorage::light_set_max_sdfgi_cascade(RID p_light, uint32_t p_cascade) {
299 Light *light = light_owner.get_or_null(p_light);
300 ERR_FAIL_COND(!light);
301
302 light->max_sdfgi_cascade = p_cascade;
303
304 light->version++;
305 light->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_LIGHT);
306}
307
308void LightStorage::light_omni_set_shadow_mode(RID p_light, RS::LightOmniShadowMode p_mode) {
309 Light *light = light_owner.get_or_null(p_light);
310 ERR_FAIL_COND(!light);
311
312 light->omni_shadow_mode = p_mode;
313
314 light->version++;
315 light->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_LIGHT);
316}
317
318RS::LightOmniShadowMode LightStorage::light_omni_get_shadow_mode(RID p_light) {
319 const Light *light = light_owner.get_or_null(p_light);
320 ERR_FAIL_COND_V(!light, RS::LIGHT_OMNI_SHADOW_CUBE);
321
322 return light->omni_shadow_mode;
323}
324
325void LightStorage::light_directional_set_shadow_mode(RID p_light, RS::LightDirectionalShadowMode p_mode) {
326 Light *light = light_owner.get_or_null(p_light);
327 ERR_FAIL_COND(!light);
328
329 light->directional_shadow_mode = p_mode;
330 light->version++;
331 light->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_LIGHT);
332}
333
334void LightStorage::light_directional_set_blend_splits(RID p_light, bool p_enable) {
335 Light *light = light_owner.get_or_null(p_light);
336 ERR_FAIL_COND(!light);
337
338 light->directional_blend_splits = p_enable;
339 light->version++;
340 light->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_LIGHT);
341}
342
343bool LightStorage::light_directional_get_blend_splits(RID p_light) const {
344 const Light *light = light_owner.get_or_null(p_light);
345 ERR_FAIL_COND_V(!light, false);
346
347 return light->directional_blend_splits;
348}
349
350void LightStorage::light_directional_set_sky_mode(RID p_light, RS::LightDirectionalSkyMode p_mode) {
351 Light *light = light_owner.get_or_null(p_light);
352 ERR_FAIL_COND(!light);
353
354 light->directional_sky_mode = p_mode;
355}
356
357RS::LightDirectionalSkyMode LightStorage::light_directional_get_sky_mode(RID p_light) const {
358 const Light *light = light_owner.get_or_null(p_light);
359 ERR_FAIL_COND_V(!light, RS::LIGHT_DIRECTIONAL_SKY_MODE_LIGHT_AND_SKY);
360
361 return light->directional_sky_mode;
362}
363
364RS::LightDirectionalShadowMode LightStorage::light_directional_get_shadow_mode(RID p_light) {
365 const Light *light = light_owner.get_or_null(p_light);
366 ERR_FAIL_COND_V(!light, RS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL);
367
368 return light->directional_shadow_mode;
369}
370
371uint32_t LightStorage::light_get_max_sdfgi_cascade(RID p_light) {
372 const Light *light = light_owner.get_or_null(p_light);
373 ERR_FAIL_COND_V(!light, 0);
374
375 return light->max_sdfgi_cascade;
376}
377
378RS::LightBakeMode LightStorage::light_get_bake_mode(RID p_light) {
379 const Light *light = light_owner.get_or_null(p_light);
380 ERR_FAIL_COND_V(!light, RS::LIGHT_BAKE_DISABLED);
381
382 return light->bake_mode;
383}
384
385uint64_t LightStorage::light_get_version(RID p_light) const {
386 const Light *light = light_owner.get_or_null(p_light);
387 ERR_FAIL_COND_V(!light, 0);
388
389 return light->version;
390}
391
392uint32_t LightStorage::light_get_cull_mask(RID p_light) const {
393 const Light *light = light_owner.get_or_null(p_light);
394 ERR_FAIL_COND_V(!light, 0);
395
396 return light->cull_mask;
397}
398
399AABB LightStorage::light_get_aabb(RID p_light) const {
400 const Light *light = light_owner.get_or_null(p_light);
401 ERR_FAIL_COND_V(!light, AABB());
402
403 switch (light->type) {
404 case RS::LIGHT_SPOT: {
405 float len = light->param[RS::LIGHT_PARAM_RANGE];
406 float size = Math::tan(Math::deg_to_rad(light->param[RS::LIGHT_PARAM_SPOT_ANGLE])) * len;
407 return AABB(Vector3(-size, -size, -len), Vector3(size * 2, size * 2, len));
408 };
409 case RS::LIGHT_OMNI: {
410 float r = light->param[RS::LIGHT_PARAM_RANGE];
411 return AABB(-Vector3(r, r, r), Vector3(r, r, r) * 2);
412 };
413 case RS::LIGHT_DIRECTIONAL: {
414 return AABB();
415 };
416 }
417
418 ERR_FAIL_V(AABB());
419}
420
421Dependency *LightStorage::light_get_dependency(RID p_light) const {
422 Light *light = light_owner.get_or_null(p_light);
423 ERR_FAIL_NULL_V(light, nullptr);
424
425 return &light->dependency;
426}
427
428/* LIGHT INSTANCE API */
429
430RID LightStorage::light_instance_create(RID p_light) {
431 RID li = light_instance_owner.make_rid(LightInstance());
432
433 LightInstance *light_instance = light_instance_owner.get_or_null(li);
434
435 light_instance->self = li;
436 light_instance->light = p_light;
437 light_instance->light_type = light_get_type(p_light);
438 if (light_instance->light_type != RS::LIGHT_DIRECTIONAL) {
439 light_instance->forward_id = ForwardIDStorage::get_singleton()->allocate_forward_id(light_instance->light_type == RS::LIGHT_OMNI ? FORWARD_ID_TYPE_OMNI_LIGHT : FORWARD_ID_TYPE_SPOT_LIGHT);
440 }
441
442 return li;
443}
444
445void LightStorage::light_instance_free(RID p_light) {
446 LightInstance *light_instance = light_instance_owner.get_or_null(p_light);
447
448 //remove from shadow atlases..
449 for (const RID &E : light_instance->shadow_atlases) {
450 ShadowAtlas *shadow_atlas = shadow_atlas_owner.get_or_null(E);
451 ERR_CONTINUE(!shadow_atlas->shadow_owners.has(p_light));
452 uint32_t key = shadow_atlas->shadow_owners[p_light];
453 uint32_t q = (key >> QUADRANT_SHIFT) & 0x3;
454 uint32_t s = key & SHADOW_INDEX_MASK;
455
456 shadow_atlas->quadrants[q].shadows.write[s].owner = RID();
457
458 if (key & OMNI_LIGHT_FLAG) {
459 // Omni lights use two atlas spots, make sure to clear the other as well
460 shadow_atlas->quadrants[q].shadows.write[s + 1].owner = RID();
461 }
462
463 shadow_atlas->shadow_owners.erase(p_light);
464 }
465
466 if (light_instance->light_type != RS::LIGHT_DIRECTIONAL) {
467 ForwardIDStorage::get_singleton()->free_forward_id(light_instance->light_type == RS::LIGHT_OMNI ? FORWARD_ID_TYPE_OMNI_LIGHT : FORWARD_ID_TYPE_SPOT_LIGHT, light_instance->forward_id);
468 }
469 light_instance_owner.free(p_light);
470}
471
472void LightStorage::light_instance_set_transform(RID p_light_instance, const Transform3D &p_transform) {
473 LightInstance *light_instance = light_instance_owner.get_or_null(p_light_instance);
474 ERR_FAIL_COND(!light_instance);
475
476 light_instance->transform = p_transform;
477}
478
479void LightStorage::light_instance_set_aabb(RID p_light_instance, const AABB &p_aabb) {
480 LightInstance *light_instance = light_instance_owner.get_or_null(p_light_instance);
481 ERR_FAIL_COND(!light_instance);
482
483 light_instance->aabb = p_aabb;
484}
485
486void LightStorage::light_instance_set_shadow_transform(RID p_light_instance, const Projection &p_projection, const Transform3D &p_transform, float p_far, float p_split, int p_pass, float p_shadow_texel_size, float p_bias_scale, float p_range_begin, const Vector2 &p_uv_scale) {
487 LightInstance *light_instance = light_instance_owner.get_or_null(p_light_instance);
488 ERR_FAIL_COND(!light_instance);
489
490 ERR_FAIL_INDEX(p_pass, 6);
491
492 light_instance->shadow_transform[p_pass].camera = p_projection;
493 light_instance->shadow_transform[p_pass].transform = p_transform;
494 light_instance->shadow_transform[p_pass].farplane = p_far;
495 light_instance->shadow_transform[p_pass].split = p_split;
496 light_instance->shadow_transform[p_pass].bias_scale = p_bias_scale;
497 light_instance->shadow_transform[p_pass].range_begin = p_range_begin;
498 light_instance->shadow_transform[p_pass].shadow_texel_size = p_shadow_texel_size;
499 light_instance->shadow_transform[p_pass].uv_scale = p_uv_scale;
500}
501
502void LightStorage::light_instance_mark_visible(RID p_light_instance) {
503 LightInstance *light_instance = light_instance_owner.get_or_null(p_light_instance);
504 ERR_FAIL_COND(!light_instance);
505
506 light_instance->last_scene_pass = RendererSceneRenderRD::get_singleton()->get_scene_pass();
507}
508
509/* LIGHT DATA */
510
511void LightStorage::free_light_data() {
512 if (directional_light_buffer.is_valid()) {
513 RD::get_singleton()->free(directional_light_buffer);
514 directional_light_buffer = RID();
515 }
516
517 if (omni_light_buffer.is_valid()) {
518 RD::get_singleton()->free(omni_light_buffer);
519 omni_light_buffer = RID();
520 }
521
522 if (spot_light_buffer.is_valid()) {
523 RD::get_singleton()->free(spot_light_buffer);
524 spot_light_buffer = RID();
525 }
526
527 if (directional_lights != nullptr) {
528 memdelete_arr(directional_lights);
529 directional_lights = nullptr;
530 }
531
532 if (omni_lights != nullptr) {
533 memdelete_arr(omni_lights);
534 omni_lights = nullptr;
535 }
536
537 if (spot_lights != nullptr) {
538 memdelete_arr(spot_lights);
539 spot_lights = nullptr;
540 }
541
542 if (omni_light_sort != nullptr) {
543 memdelete_arr(omni_light_sort);
544 omni_light_sort = nullptr;
545 }
546
547 if (spot_light_sort != nullptr) {
548 memdelete_arr(spot_light_sort);
549 spot_light_sort = nullptr;
550 }
551}
552
553void LightStorage::set_max_lights(const uint32_t p_max_lights) {
554 max_lights = p_max_lights;
555
556 uint32_t light_buffer_size = max_lights * sizeof(LightData);
557 omni_lights = memnew_arr(LightData, max_lights);
558 omni_light_buffer = RD::get_singleton()->storage_buffer_create(light_buffer_size);
559 omni_light_sort = memnew_arr(LightInstanceDepthSort, max_lights);
560 spot_lights = memnew_arr(LightData, max_lights);
561 spot_light_buffer = RD::get_singleton()->storage_buffer_create(light_buffer_size);
562 spot_light_sort = memnew_arr(LightInstanceDepthSort, max_lights);
563 //defines += "\n#define MAX_LIGHT_DATA_STRUCTS " + itos(max_lights) + "\n";
564
565 max_directional_lights = RendererSceneRender::MAX_DIRECTIONAL_LIGHTS;
566 uint32_t directional_light_buffer_size = max_directional_lights * sizeof(DirectionalLightData);
567 directional_lights = memnew_arr(DirectionalLightData, max_directional_lights);
568 directional_light_buffer = RD::get_singleton()->uniform_buffer_create(directional_light_buffer_size);
569}
570
571void LightStorage::update_light_buffers(RenderDataRD *p_render_data, const PagedArray<RID> &p_lights, const Transform3D &p_camera_transform, RID p_shadow_atlas, bool p_using_shadows, uint32_t &r_directional_light_count, uint32_t &r_positional_light_count, bool &r_directional_light_soft_shadows) {
572 ForwardIDStorage *forward_id_storage = ForwardIDStorage::get_singleton();
573 RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
574
575 Transform3D inverse_transform = p_camera_transform.affine_inverse();
576
577 r_directional_light_count = 0;
578 r_positional_light_count = 0;
579
580 omni_light_count = 0;
581 spot_light_count = 0;
582
583 r_directional_light_soft_shadows = false;
584
585 for (int i = 0; i < (int)p_lights.size(); i++) {
586 LightInstance *light_instance = light_instance_owner.get_or_null(p_lights[i]);
587 if (!light_instance) {
588 continue;
589 }
590 Light *light = light_owner.get_or_null(light_instance->light);
591
592 ERR_CONTINUE(light == nullptr);
593
594 switch (light->type) {
595 case RS::LIGHT_DIRECTIONAL: {
596 if (r_directional_light_count >= max_directional_lights || light->directional_sky_mode == RS::LIGHT_DIRECTIONAL_SKY_MODE_SKY_ONLY) {
597 continue;
598 }
599
600 DirectionalLightData &light_data = directional_lights[r_directional_light_count];
601
602 Transform3D light_transform = light_instance->transform;
603
604 Vector3 direction = inverse_transform.basis.xform(light_transform.basis.xform(Vector3(0, 0, 1))).normalized();
605
606 light_data.direction[0] = direction.x;
607 light_data.direction[1] = direction.y;
608 light_data.direction[2] = direction.z;
609
610 float sign = light->negative ? -1 : 1;
611
612 light_data.energy = sign * light->param[RS::LIGHT_PARAM_ENERGY];
613
614 if (RendererSceneRenderRD::get_singleton()->is_using_physical_light_units()) {
615 light_data.energy *= light->param[RS::LIGHT_PARAM_INTENSITY];
616 } else {
617 light_data.energy *= Math_PI;
618 }
619
620 if (p_render_data->camera_attributes.is_valid()) {
621 light_data.energy *= RSG::camera_attributes->camera_attributes_get_exposure_normalization_factor(p_render_data->camera_attributes);
622 }
623
624 Color linear_col = light->color.srgb_to_linear();
625 light_data.color[0] = linear_col.r;
626 light_data.color[1] = linear_col.g;
627 light_data.color[2] = linear_col.b;
628
629 light_data.specular = light->param[RS::LIGHT_PARAM_SPECULAR];
630 light_data.volumetric_fog_energy = light->param[RS::LIGHT_PARAM_VOLUMETRIC_FOG_ENERGY];
631 light_data.mask = light->cull_mask;
632
633 float size = light->param[RS::LIGHT_PARAM_SIZE];
634
635 light_data.size = 1.0 - Math::cos(Math::deg_to_rad(size)); //angle to cosine offset
636
637 light_data.shadow_opacity = (p_using_shadows && light->shadow)
638 ? light->param[RS::LIGHT_PARAM_SHADOW_OPACITY]
639 : 0.0;
640
641 float angular_diameter = light->param[RS::LIGHT_PARAM_SIZE];
642 if (angular_diameter > 0.0) {
643 // I know tan(0) is 0, but let's not risk it with numerical precision.
644 // technically this will keep expanding until reaching the sun, but all we care
645 // is expand until we reach the radius of the near plane (there can't be more occluders than that)
646 angular_diameter = Math::tan(Math::deg_to_rad(angular_diameter));
647 if (light->shadow && light->param[RS::LIGHT_PARAM_SHADOW_BLUR] > 0.0) {
648 // Only enable PCSS-like soft shadows if blurring is enabled.
649 // Otherwise, performance would decrease with no visual difference.
650 r_directional_light_soft_shadows = true;
651 }
652 } else {
653 angular_diameter = 0.0;
654 }
655
656 if (light_data.shadow_opacity > 0.001) {
657 RS::LightDirectionalShadowMode smode = light->directional_shadow_mode;
658
659 light_data.soft_shadow_scale = light->param[RS::LIGHT_PARAM_SHADOW_BLUR];
660 light_data.softshadow_angle = angular_diameter;
661 light_data.bake_mode = light->bake_mode;
662
663 if (angular_diameter <= 0.0) {
664 light_data.soft_shadow_scale *= RendererSceneRenderRD::get_singleton()->directional_shadow_quality_radius_get(); // Only use quality radius for PCF
665 }
666
667 int limit = smode == RS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL ? 0 : (smode == RS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS ? 1 : 3);
668 light_data.blend_splits = (smode != RS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL) && light->directional_blend_splits;
669 for (int j = 0; j < 4; j++) {
670 Rect2 atlas_rect = light_instance->shadow_transform[j].atlas_rect;
671 Projection matrix = light_instance->shadow_transform[j].camera;
672 float split = light_instance->shadow_transform[MIN(limit, j)].split;
673
674 Projection bias;
675 bias.set_light_bias();
676 Projection rectm;
677 rectm.set_light_atlas_rect(atlas_rect);
678
679 Transform3D modelview = (inverse_transform * light_instance->shadow_transform[j].transform).inverse();
680
681 Projection shadow_mtx = rectm * bias * matrix * modelview;
682 light_data.shadow_split_offsets[j] = split;
683 float bias_scale = light_instance->shadow_transform[j].bias_scale * light_data.soft_shadow_scale;
684 light_data.shadow_bias[j] = light->param[RS::LIGHT_PARAM_SHADOW_BIAS] / 100.0 * bias_scale;
685 light_data.shadow_normal_bias[j] = light->param[RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS] * light_instance->shadow_transform[j].shadow_texel_size;
686 light_data.shadow_transmittance_bias[j] = light->param[RS::LIGHT_PARAM_TRANSMITTANCE_BIAS] * bias_scale;
687 light_data.shadow_z_range[j] = light_instance->shadow_transform[j].farplane;
688 light_data.shadow_range_begin[j] = light_instance->shadow_transform[j].range_begin;
689 RendererRD::MaterialStorage::store_camera(shadow_mtx, light_data.shadow_matrices[j]);
690
691 Vector2 uv_scale = light_instance->shadow_transform[j].uv_scale;
692 uv_scale *= atlas_rect.size; //adapt to atlas size
693 switch (j) {
694 case 0: {
695 light_data.uv_scale1[0] = uv_scale.x;
696 light_data.uv_scale1[1] = uv_scale.y;
697 } break;
698 case 1: {
699 light_data.uv_scale2[0] = uv_scale.x;
700 light_data.uv_scale2[1] = uv_scale.y;
701 } break;
702 case 2: {
703 light_data.uv_scale3[0] = uv_scale.x;
704 light_data.uv_scale3[1] = uv_scale.y;
705 } break;
706 case 3: {
707 light_data.uv_scale4[0] = uv_scale.x;
708 light_data.uv_scale4[1] = uv_scale.y;
709 } break;
710 }
711 }
712
713 float fade_start = light->param[RS::LIGHT_PARAM_SHADOW_FADE_START];
714 light_data.fade_from = -light_data.shadow_split_offsets[3] * MIN(fade_start, 0.999); //using 1.0 would break smoothstep
715 light_data.fade_to = -light_data.shadow_split_offsets[3];
716 }
717
718 r_directional_light_count++;
719 } break;
720 case RS::LIGHT_OMNI: {
721 if (omni_light_count >= max_lights) {
722 continue;
723 }
724
725 Transform3D light_transform = light_instance->transform;
726 const real_t distance = p_camera_transform.origin.distance_to(light_transform.origin);
727
728 if (light->distance_fade) {
729 const float fade_begin = light->distance_fade_begin;
730 const float fade_length = light->distance_fade_length;
731
732 if (distance > fade_begin) {
733 if (distance > fade_begin + fade_length) {
734 // Out of range, don't draw this light to improve performance.
735 continue;
736 }
737 }
738 }
739
740 omni_light_sort[omni_light_count].light_instance = light_instance;
741 omni_light_sort[omni_light_count].light = light;
742 omni_light_sort[omni_light_count].depth = distance;
743 omni_light_count++;
744 } break;
745 case RS::LIGHT_SPOT: {
746 if (spot_light_count >= max_lights) {
747 continue;
748 }
749
750 Transform3D light_transform = light_instance->transform;
751 const real_t distance = p_camera_transform.origin.distance_to(light_transform.origin);
752
753 if (light->distance_fade) {
754 const float fade_begin = light->distance_fade_begin;
755 const float fade_length = light->distance_fade_length;
756
757 if (distance > fade_begin) {
758 if (distance > fade_begin + fade_length) {
759 // Out of range, don't draw this light to improve performance.
760 continue;
761 }
762 }
763 }
764
765 spot_light_sort[spot_light_count].light_instance = light_instance;
766 spot_light_sort[spot_light_count].light = light;
767 spot_light_sort[spot_light_count].depth = distance;
768 spot_light_count++;
769 } break;
770 }
771
772 light_instance->last_pass = RSG::rasterizer->get_frame_number();
773 }
774
775 if (omni_light_count) {
776 SortArray<LightInstanceDepthSort> sorter;
777 sorter.sort(omni_light_sort, omni_light_count);
778 }
779
780 if (spot_light_count) {
781 SortArray<LightInstanceDepthSort> sorter;
782 sorter.sort(spot_light_sort, spot_light_count);
783 }
784
785 bool using_forward_ids = forward_id_storage->uses_forward_ids();
786
787 for (uint32_t i = 0; i < (omni_light_count + spot_light_count); i++) {
788 uint32_t index = (i < omni_light_count) ? i : i - (omni_light_count);
789 LightData &light_data = (i < omni_light_count) ? omni_lights[index] : spot_lights[index];
790 RS::LightType type = (i < omni_light_count) ? RS::LIGHT_OMNI : RS::LIGHT_SPOT;
791 LightInstance *light_instance = (i < omni_light_count) ? omni_light_sort[index].light_instance : spot_light_sort[index].light_instance;
792 Light *light = (i < omni_light_count) ? omni_light_sort[index].light : spot_light_sort[index].light;
793 real_t distance = (i < omni_light_count) ? omni_light_sort[index].depth : spot_light_sort[index].depth;
794
795 if (using_forward_ids) {
796 forward_id_storage->map_forward_id(type == RS::LIGHT_OMNI ? RendererRD::FORWARD_ID_TYPE_OMNI_LIGHT : RendererRD::FORWARD_ID_TYPE_SPOT_LIGHT, light_instance->forward_id, index);
797 }
798
799 Transform3D light_transform = light_instance->transform;
800
801 float sign = light->negative ? -1 : 1;
802 Color linear_col = light->color.srgb_to_linear();
803
804 light_data.attenuation = light->param[RS::LIGHT_PARAM_ATTENUATION];
805
806 // Reuse fade begin, fade length and distance for shadow LOD determination later.
807 float fade_begin = 0.0;
808 float fade_shadow = 0.0;
809 float fade_length = 0.0;
810
811 float fade = 1.0;
812 float shadow_opacity_fade = 1.0;
813 if (light->distance_fade) {
814 fade_begin = light->distance_fade_begin;
815 fade_shadow = light->distance_fade_shadow;
816 fade_length = light->distance_fade_length;
817
818 // Use `smoothstep()` to make opacity changes more gradual and less noticeable to the player.
819 if (distance > fade_begin) {
820 fade = Math::smoothstep(0.0f, 1.0f, 1.0f - float(distance - fade_begin) / fade_length);
821 }
822
823 if (distance > fade_shadow) {
824 shadow_opacity_fade = Math::smoothstep(0.0f, 1.0f, 1.0f - float(distance - fade_shadow) / fade_length);
825 }
826 }
827
828 float energy = sign * light->param[RS::LIGHT_PARAM_ENERGY] * fade;
829
830 if (RendererSceneRenderRD::get_singleton()->is_using_physical_light_units()) {
831 energy *= light->param[RS::LIGHT_PARAM_INTENSITY];
832
833 // Convert from Luminous Power to Luminous Intensity
834 if (type == RS::LIGHT_OMNI) {
835 energy *= 1.0 / (Math_PI * 4.0);
836 } else {
837 // Spot Lights are not physically accurate, Luminous Intensity should change in relation to the cone angle.
838 // We make this assumption to keep them easy to control.
839 energy *= 1.0 / Math_PI;
840 }
841 } else {
842 energy *= Math_PI;
843 }
844
845 if (p_render_data->camera_attributes.is_valid()) {
846 energy *= RSG::camera_attributes->camera_attributes_get_exposure_normalization_factor(p_render_data->camera_attributes);
847 }
848
849 light_data.color[0] = linear_col.r * energy;
850 light_data.color[1] = linear_col.g * energy;
851 light_data.color[2] = linear_col.b * energy;
852 light_data.specular_amount = light->param[RS::LIGHT_PARAM_SPECULAR] * 2.0;
853 light_data.volumetric_fog_energy = light->param[RS::LIGHT_PARAM_VOLUMETRIC_FOG_ENERGY];
854 light_data.bake_mode = light->bake_mode;
855
856 float radius = MAX(0.001, light->param[RS::LIGHT_PARAM_RANGE]);
857 light_data.inv_radius = 1.0 / radius;
858
859 Vector3 pos = inverse_transform.xform(light_transform.origin);
860
861 light_data.position[0] = pos.x;
862 light_data.position[1] = pos.y;
863 light_data.position[2] = pos.z;
864
865 Vector3 direction = inverse_transform.basis.xform(light_transform.basis.xform(Vector3(0, 0, -1))).normalized();
866
867 light_data.direction[0] = direction.x;
868 light_data.direction[1] = direction.y;
869 light_data.direction[2] = direction.z;
870
871 float size = light->param[RS::LIGHT_PARAM_SIZE];
872
873 light_data.size = size;
874
875 light_data.inv_spot_attenuation = 1.0f / light->param[RS::LIGHT_PARAM_SPOT_ATTENUATION];
876 float spot_angle = light->param[RS::LIGHT_PARAM_SPOT_ANGLE];
877 light_data.cos_spot_angle = Math::cos(Math::deg_to_rad(spot_angle));
878
879 light_data.mask = light->cull_mask;
880
881 light_data.atlas_rect[0] = 0;
882 light_data.atlas_rect[1] = 0;
883 light_data.atlas_rect[2] = 0;
884 light_data.atlas_rect[3] = 0;
885
886 RID projector = light->projector;
887
888 if (projector.is_valid()) {
889 Rect2 rect = texture_storage->decal_atlas_get_texture_rect(projector);
890
891 if (type == RS::LIGHT_SPOT) {
892 light_data.projector_rect[0] = rect.position.x;
893 light_data.projector_rect[1] = rect.position.y + rect.size.height; //flip because shadow is flipped
894 light_data.projector_rect[2] = rect.size.width;
895 light_data.projector_rect[3] = -rect.size.height;
896 } else {
897 light_data.projector_rect[0] = rect.position.x;
898 light_data.projector_rect[1] = rect.position.y;
899 light_data.projector_rect[2] = rect.size.width;
900 light_data.projector_rect[3] = rect.size.height * 0.5; //used by dp, so needs to be half
901 }
902 } else {
903 light_data.projector_rect[0] = 0;
904 light_data.projector_rect[1] = 0;
905 light_data.projector_rect[2] = 0;
906 light_data.projector_rect[3] = 0;
907 }
908
909 const bool needs_shadow =
910 p_using_shadows &&
911 owns_shadow_atlas(p_shadow_atlas) &&
912 shadow_atlas_owns_light_instance(p_shadow_atlas, light_instance->self) &&
913 light->shadow;
914
915 bool in_shadow_range = true;
916 if (needs_shadow && light->distance_fade) {
917 if (distance > light->distance_fade_shadow + light->distance_fade_length) {
918 // Out of range, don't draw shadows to improve performance.
919 in_shadow_range = false;
920 }
921 }
922
923 if (needs_shadow && in_shadow_range) {
924 // fill in the shadow information
925
926 light_data.shadow_opacity = light->param[RS::LIGHT_PARAM_SHADOW_OPACITY] * shadow_opacity_fade;
927
928 float shadow_texel_size = light_instance_get_shadow_texel_size(light_instance->self, p_shadow_atlas);
929 light_data.shadow_normal_bias = light->param[RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS] * shadow_texel_size * 10.0;
930
931 if (type == RS::LIGHT_SPOT) {
932 light_data.shadow_bias = light->param[RS::LIGHT_PARAM_SHADOW_BIAS] / 100.0;
933 } else { //omni
934 light_data.shadow_bias = light->param[RS::LIGHT_PARAM_SHADOW_BIAS];
935 }
936
937 light_data.transmittance_bias = light->param[RS::LIGHT_PARAM_TRANSMITTANCE_BIAS];
938
939 Vector2i omni_offset;
940 Rect2 rect = light_instance_get_shadow_atlas_rect(light_instance->self, p_shadow_atlas, omni_offset);
941
942 light_data.atlas_rect[0] = rect.position.x;
943 light_data.atlas_rect[1] = rect.position.y;
944 light_data.atlas_rect[2] = rect.size.width;
945 light_data.atlas_rect[3] = rect.size.height;
946
947 light_data.soft_shadow_scale = light->param[RS::LIGHT_PARAM_SHADOW_BLUR];
948
949 if (type == RS::LIGHT_OMNI) {
950 Transform3D proj = (inverse_transform * light_transform).inverse();
951
952 RendererRD::MaterialStorage::store_transform(proj, light_data.shadow_matrix);
953
954 if (size > 0.0 && light_data.soft_shadow_scale > 0.0) {
955 // Only enable PCSS-like soft shadows if blurring is enabled.
956 // Otherwise, performance would decrease with no visual difference.
957 light_data.soft_shadow_size = size;
958 } else {
959 light_data.soft_shadow_size = 0.0;
960 light_data.soft_shadow_scale *= RendererSceneRenderRD::get_singleton()->shadows_quality_radius_get(); // Only use quality radius for PCF
961 }
962
963 light_data.direction[0] = omni_offset.x * float(rect.size.width);
964 light_data.direction[1] = omni_offset.y * float(rect.size.height);
965 } else if (type == RS::LIGHT_SPOT) {
966 Transform3D modelview = (inverse_transform * light_transform).inverse();
967 Projection bias;
968 bias.set_light_bias();
969
970 Projection cm = light_instance->shadow_transform[0].camera;
971 Projection shadow_mtx = bias * cm * modelview;
972 RendererRD::MaterialStorage::store_camera(shadow_mtx, light_data.shadow_matrix);
973
974 if (size > 0.0 && light_data.soft_shadow_scale > 0.0) {
975 // Only enable PCSS-like soft shadows if blurring is enabled.
976 // Otherwise, performance would decrease with no visual difference.
977 float half_np = cm.get_z_near() * Math::tan(Math::deg_to_rad(spot_angle));
978 light_data.soft_shadow_size = (size * 0.5 / radius) / (half_np / cm.get_z_near()) * rect.size.width;
979 } else {
980 light_data.soft_shadow_size = 0.0;
981 light_data.soft_shadow_scale *= RendererSceneRenderRD::get_singleton()->shadows_quality_radius_get(); // Only use quality radius for PCF
982 }
983 light_data.shadow_bias *= light_data.soft_shadow_scale;
984 }
985 } else {
986 light_data.shadow_opacity = 0.0;
987 }
988
989 light_instance->cull_mask = light->cull_mask;
990
991 // hook for subclass to do further processing.
992 RendererSceneRenderRD::get_singleton()->setup_added_light(type, light_transform, radius, spot_angle);
993
994 r_positional_light_count++;
995 }
996
997 //update without barriers
998 if (omni_light_count) {
999 RD::get_singleton()->buffer_update(omni_light_buffer, 0, sizeof(LightData) * omni_light_count, omni_lights, RD::BARRIER_MASK_RASTER | RD::BARRIER_MASK_COMPUTE);
1000 }
1001
1002 if (spot_light_count) {
1003 RD::get_singleton()->buffer_update(spot_light_buffer, 0, sizeof(LightData) * spot_light_count, spot_lights, RD::BARRIER_MASK_RASTER | RD::BARRIER_MASK_COMPUTE);
1004 }
1005
1006 if (r_directional_light_count) {
1007 RD::get_singleton()->buffer_update(directional_light_buffer, 0, sizeof(DirectionalLightData) * r_directional_light_count, directional_lights, RD::BARRIER_MASK_RASTER | RD::BARRIER_MASK_COMPUTE);
1008 }
1009}
1010
1011/* REFLECTION PROBE */
1012
1013RID LightStorage::reflection_probe_allocate() {
1014 return reflection_probe_owner.allocate_rid();
1015}
1016
1017void LightStorage::reflection_probe_initialize(RID p_reflection_probe) {
1018 reflection_probe_owner.initialize_rid(p_reflection_probe, ReflectionProbe());
1019}
1020
1021void LightStorage::reflection_probe_free(RID p_rid) {
1022 ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_rid);
1023 reflection_probe->dependency.deleted_notify(p_rid);
1024 reflection_probe_owner.free(p_rid);
1025};
1026
1027void LightStorage::reflection_probe_set_update_mode(RID p_probe, RS::ReflectionProbeUpdateMode p_mode) {
1028 ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
1029 ERR_FAIL_COND(!reflection_probe);
1030
1031 reflection_probe->update_mode = p_mode;
1032 reflection_probe->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_REFLECTION_PROBE);
1033}
1034
1035void LightStorage::reflection_probe_set_intensity(RID p_probe, float p_intensity) {
1036 ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
1037 ERR_FAIL_COND(!reflection_probe);
1038
1039 reflection_probe->intensity = p_intensity;
1040}
1041
1042void LightStorage::reflection_probe_set_ambient_mode(RID p_probe, RS::ReflectionProbeAmbientMode p_mode) {
1043 ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
1044 ERR_FAIL_COND(!reflection_probe);
1045
1046 reflection_probe->ambient_mode = p_mode;
1047}
1048
1049void LightStorage::reflection_probe_set_ambient_color(RID p_probe, const Color &p_color) {
1050 ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
1051 ERR_FAIL_COND(!reflection_probe);
1052
1053 reflection_probe->ambient_color = p_color;
1054}
1055
1056void LightStorage::reflection_probe_set_ambient_energy(RID p_probe, float p_energy) {
1057 ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
1058 ERR_FAIL_COND(!reflection_probe);
1059
1060 reflection_probe->ambient_color_energy = p_energy;
1061}
1062
1063void LightStorage::reflection_probe_set_max_distance(RID p_probe, float p_distance) {
1064 ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
1065 ERR_FAIL_COND(!reflection_probe);
1066
1067 reflection_probe->max_distance = p_distance;
1068
1069 reflection_probe->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_REFLECTION_PROBE);
1070}
1071
1072void LightStorage::reflection_probe_set_size(RID p_probe, const Vector3 &p_size) {
1073 ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
1074 ERR_FAIL_COND(!reflection_probe);
1075
1076 if (reflection_probe->size == p_size) {
1077 return;
1078 }
1079 reflection_probe->size = p_size;
1080 reflection_probe->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_REFLECTION_PROBE);
1081}
1082
1083void LightStorage::reflection_probe_set_origin_offset(RID p_probe, const Vector3 &p_offset) {
1084 ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
1085 ERR_FAIL_COND(!reflection_probe);
1086
1087 reflection_probe->origin_offset = p_offset;
1088 reflection_probe->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_REFLECTION_PROBE);
1089}
1090
1091void LightStorage::reflection_probe_set_as_interior(RID p_probe, bool p_enable) {
1092 ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
1093 ERR_FAIL_COND(!reflection_probe);
1094
1095 reflection_probe->interior = p_enable;
1096 reflection_probe->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_REFLECTION_PROBE);
1097}
1098
1099void LightStorage::reflection_probe_set_enable_box_projection(RID p_probe, bool p_enable) {
1100 ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
1101 ERR_FAIL_COND(!reflection_probe);
1102
1103 reflection_probe->box_projection = p_enable;
1104}
1105
1106void LightStorage::reflection_probe_set_enable_shadows(RID p_probe, bool p_enable) {
1107 ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
1108 ERR_FAIL_COND(!reflection_probe);
1109
1110 reflection_probe->enable_shadows = p_enable;
1111 reflection_probe->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_REFLECTION_PROBE);
1112}
1113
1114void LightStorage::reflection_probe_set_cull_mask(RID p_probe, uint32_t p_layers) {
1115 ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
1116 ERR_FAIL_COND(!reflection_probe);
1117
1118 reflection_probe->cull_mask = p_layers;
1119 reflection_probe->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_REFLECTION_PROBE);
1120}
1121
1122void LightStorage::reflection_probe_set_resolution(RID p_probe, int p_resolution) {
1123 ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
1124 ERR_FAIL_COND(!reflection_probe);
1125 ERR_FAIL_COND(p_resolution < 32);
1126
1127 reflection_probe->resolution = p_resolution;
1128}
1129
1130void LightStorage::reflection_probe_set_mesh_lod_threshold(RID p_probe, float p_ratio) {
1131 ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
1132 ERR_FAIL_COND(!reflection_probe);
1133
1134 reflection_probe->mesh_lod_threshold = p_ratio;
1135
1136 reflection_probe->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_REFLECTION_PROBE);
1137}
1138
1139void LightStorage::reflection_probe_set_baked_exposure(RID p_probe, float p_exposure) {
1140 ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
1141 ERR_FAIL_COND(!reflection_probe);
1142
1143 reflection_probe->baked_exposure = p_exposure;
1144}
1145
1146AABB LightStorage::reflection_probe_get_aabb(RID p_probe) const {
1147 const ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
1148 ERR_FAIL_COND_V(!reflection_probe, AABB());
1149
1150 AABB aabb;
1151 aabb.position = -reflection_probe->size / 2;
1152 aabb.size = reflection_probe->size;
1153
1154 return aabb;
1155}
1156
1157RS::ReflectionProbeUpdateMode LightStorage::reflection_probe_get_update_mode(RID p_probe) const {
1158 const ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
1159 ERR_FAIL_COND_V(!reflection_probe, RS::REFLECTION_PROBE_UPDATE_ALWAYS);
1160
1161 return reflection_probe->update_mode;
1162}
1163
1164uint32_t LightStorage::reflection_probe_get_cull_mask(RID p_probe) const {
1165 const ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
1166 ERR_FAIL_COND_V(!reflection_probe, 0);
1167
1168 return reflection_probe->cull_mask;
1169}
1170
1171Vector3 LightStorage::reflection_probe_get_size(RID p_probe) const {
1172 const ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
1173 ERR_FAIL_COND_V(!reflection_probe, Vector3());
1174
1175 return reflection_probe->size;
1176}
1177
1178Vector3 LightStorage::reflection_probe_get_origin_offset(RID p_probe) const {
1179 const ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
1180 ERR_FAIL_COND_V(!reflection_probe, Vector3());
1181
1182 return reflection_probe->origin_offset;
1183}
1184
1185bool LightStorage::reflection_probe_renders_shadows(RID p_probe) const {
1186 const ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
1187 ERR_FAIL_COND_V(!reflection_probe, false);
1188
1189 return reflection_probe->enable_shadows;
1190}
1191
1192float LightStorage::reflection_probe_get_origin_max_distance(RID p_probe) const {
1193 const ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
1194 ERR_FAIL_COND_V(!reflection_probe, 0);
1195
1196 return reflection_probe->max_distance;
1197}
1198
1199float LightStorage::reflection_probe_get_mesh_lod_threshold(RID p_probe) const {
1200 const ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
1201 ERR_FAIL_COND_V(!reflection_probe, 0);
1202
1203 return reflection_probe->mesh_lod_threshold;
1204}
1205
1206int LightStorage::reflection_probe_get_resolution(RID p_probe) const {
1207 const ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
1208 ERR_FAIL_COND_V(!reflection_probe, 0);
1209
1210 return reflection_probe->resolution;
1211}
1212
1213float LightStorage::reflection_probe_get_baked_exposure(RID p_probe) const {
1214 const ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
1215 ERR_FAIL_COND_V(!reflection_probe, 1.0);
1216
1217 return reflection_probe->baked_exposure;
1218}
1219
1220float LightStorage::reflection_probe_get_intensity(RID p_probe) const {
1221 const ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
1222 ERR_FAIL_COND_V(!reflection_probe, 0);
1223
1224 return reflection_probe->intensity;
1225}
1226
1227bool LightStorage::reflection_probe_is_interior(RID p_probe) const {
1228 const ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
1229 ERR_FAIL_COND_V(!reflection_probe, false);
1230
1231 return reflection_probe->interior;
1232}
1233
1234bool LightStorage::reflection_probe_is_box_projection(RID p_probe) const {
1235 const ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
1236 ERR_FAIL_COND_V(!reflection_probe, false);
1237
1238 return reflection_probe->box_projection;
1239}
1240
1241RS::ReflectionProbeAmbientMode LightStorage::reflection_probe_get_ambient_mode(RID p_probe) const {
1242 const ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
1243 ERR_FAIL_COND_V(!reflection_probe, RS::REFLECTION_PROBE_AMBIENT_DISABLED);
1244 return reflection_probe->ambient_mode;
1245}
1246
1247Color LightStorage::reflection_probe_get_ambient_color(RID p_probe) const {
1248 const ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
1249 ERR_FAIL_COND_V(!reflection_probe, Color());
1250
1251 return reflection_probe->ambient_color;
1252}
1253float LightStorage::reflection_probe_get_ambient_color_energy(RID p_probe) const {
1254 const ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
1255 ERR_FAIL_COND_V(!reflection_probe, 0);
1256
1257 return reflection_probe->ambient_color_energy;
1258}
1259
1260Dependency *LightStorage::reflection_probe_get_dependency(RID p_probe) const {
1261 ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
1262 ERR_FAIL_NULL_V(reflection_probe, nullptr);
1263
1264 return &reflection_probe->dependency;
1265}
1266
1267/* REFLECTION ATLAS */
1268
1269RID LightStorage::reflection_atlas_create() {
1270 ReflectionAtlas ra;
1271 ra.count = GLOBAL_GET("rendering/reflections/reflection_atlas/reflection_count");
1272 ra.size = GLOBAL_GET("rendering/reflections/reflection_atlas/reflection_size");
1273 ra.cluster_builder = nullptr;
1274
1275 return reflection_atlas_owner.make_rid(ra);
1276}
1277
1278void LightStorage::reflection_atlas_free(RID p_ref_atlas) {
1279 reflection_atlas_set_size(p_ref_atlas, 0, 0);
1280 ReflectionAtlas *ra = reflection_atlas_owner.get_or_null(p_ref_atlas);
1281 if (ra->cluster_builder) {
1282 memdelete(ra->cluster_builder);
1283 }
1284 reflection_atlas_owner.free(p_ref_atlas);
1285}
1286
1287void LightStorage::reflection_atlas_set_size(RID p_ref_atlas, int p_reflection_size, int p_reflection_count) {
1288 ReflectionAtlas *ra = reflection_atlas_owner.get_or_null(p_ref_atlas);
1289 ERR_FAIL_COND(!ra);
1290
1291 if (ra->size == p_reflection_size && ra->count == p_reflection_count) {
1292 return; //no changes
1293 }
1294
1295 if (ra->cluster_builder) {
1296 // only if we're using our cluster
1297 ra->cluster_builder->setup(Size2i(ra->size, ra->size), max_cluster_elements, RID(), RID(), RID());
1298 }
1299
1300 ra->size = p_reflection_size;
1301 ra->count = p_reflection_count;
1302
1303 if (ra->reflection.is_valid()) {
1304 //clear and invalidate everything
1305 RD::get_singleton()->free(ra->reflection);
1306 ra->reflection = RID();
1307 RD::get_singleton()->free(ra->depth_buffer);
1308 ra->depth_buffer = RID();
1309 for (int i = 0; i < ra->reflections.size(); i++) {
1310 ra->reflections.write[i].data.clear_reflection_data();
1311 if (ra->reflections[i].owner.is_null()) {
1312 continue;
1313 }
1314 reflection_probe_release_atlas_index(ra->reflections[i].owner);
1315 //rp->atlasindex clear
1316 }
1317
1318 ra->reflections.clear();
1319 }
1320
1321 if (ra->render_buffers.is_valid()) {
1322 ra->render_buffers->cleanup();
1323 }
1324}
1325
1326int LightStorage::reflection_atlas_get_size(RID p_ref_atlas) const {
1327 ReflectionAtlas *ra = reflection_atlas_owner.get_or_null(p_ref_atlas);
1328 ERR_FAIL_COND_V(!ra, 0);
1329
1330 return ra->size;
1331}
1332
1333/* REFLECTION PROBE INSTANCE */
1334
1335RID LightStorage::reflection_probe_instance_create(RID p_probe) {
1336 ReflectionProbeInstance rpi;
1337 rpi.probe = p_probe;
1338 rpi.forward_id = ForwardIDStorage::get_singleton()->allocate_forward_id(FORWARD_ID_TYPE_REFLECTION_PROBE);
1339
1340 return reflection_probe_instance_owner.make_rid(rpi);
1341}
1342
1343void LightStorage::reflection_probe_instance_free(RID p_instance) {
1344 ReflectionProbeInstance *rpi = reflection_probe_instance_owner.get_or_null(p_instance);
1345 ForwardIDStorage::get_singleton()->free_forward_id(FORWARD_ID_TYPE_REFLECTION_PROBE, rpi->forward_id);
1346 reflection_probe_release_atlas_index(p_instance);
1347 reflection_probe_instance_owner.free(p_instance);
1348}
1349
1350void LightStorage::reflection_probe_instance_set_transform(RID p_instance, const Transform3D &p_transform) {
1351 ReflectionProbeInstance *rpi = reflection_probe_instance_owner.get_or_null(p_instance);
1352 ERR_FAIL_COND(!rpi);
1353
1354 rpi->transform = p_transform;
1355 rpi->dirty = true;
1356}
1357
1358void LightStorage::reflection_probe_release_atlas_index(RID p_instance) {
1359 ReflectionProbeInstance *rpi = reflection_probe_instance_owner.get_or_null(p_instance);
1360 ERR_FAIL_COND(!rpi);
1361
1362 if (rpi->atlas.is_null()) {
1363 return; //nothing to release
1364 }
1365 ReflectionAtlas *atlas = reflection_atlas_owner.get_or_null(rpi->atlas);
1366 ERR_FAIL_COND(!atlas);
1367 ERR_FAIL_INDEX(rpi->atlas_index, atlas->reflections.size());
1368 atlas->reflections.write[rpi->atlas_index].owner = RID();
1369
1370 // TODO investigate if this is enough? shouldn't we be freeing our textures and framebuffers?
1371
1372 rpi->atlas_index = -1;
1373 rpi->atlas = RID();
1374}
1375
1376bool LightStorage::reflection_probe_instance_needs_redraw(RID p_instance) {
1377 ReflectionProbeInstance *rpi = reflection_probe_instance_owner.get_or_null(p_instance);
1378 ERR_FAIL_COND_V(!rpi, false);
1379
1380 if (rpi->rendering) {
1381 return false;
1382 }
1383
1384 if (rpi->dirty) {
1385 return true;
1386 }
1387
1388 if (LightStorage::get_singleton()->reflection_probe_get_update_mode(rpi->probe) == RS::REFLECTION_PROBE_UPDATE_ALWAYS) {
1389 return true;
1390 }
1391
1392 return rpi->atlas_index == -1;
1393}
1394
1395bool LightStorage::reflection_probe_instance_has_reflection(RID p_instance) {
1396 ReflectionProbeInstance *rpi = reflection_probe_instance_owner.get_or_null(p_instance);
1397 ERR_FAIL_COND_V(!rpi, false);
1398
1399 return rpi->atlas.is_valid();
1400}
1401
1402bool LightStorage::reflection_probe_instance_begin_render(RID p_instance, RID p_reflection_atlas) {
1403 ReflectionAtlas *atlas = reflection_atlas_owner.get_or_null(p_reflection_atlas);
1404
1405 ERR_FAIL_COND_V(!atlas, false);
1406
1407 ReflectionProbeInstance *rpi = reflection_probe_instance_owner.get_or_null(p_instance);
1408 ERR_FAIL_COND_V(!rpi, false);
1409
1410 if (atlas->render_buffers.is_null()) {
1411 atlas->render_buffers.instantiate();
1412 }
1413
1414 RD::get_singleton()->draw_command_begin_label("Reflection probe render");
1415
1416 if (LightStorage::get_singleton()->reflection_probe_get_update_mode(rpi->probe) == RS::REFLECTION_PROBE_UPDATE_ALWAYS && atlas->reflection.is_valid() && atlas->size != 256) {
1417 WARN_PRINT("ReflectionProbes set to UPDATE_ALWAYS must have an atlas size of 256. Please update the atlas size in the ProjectSettings.");
1418 reflection_atlas_set_size(p_reflection_atlas, 256, atlas->count);
1419 }
1420
1421 if (LightStorage::get_singleton()->reflection_probe_get_update_mode(rpi->probe) == RS::REFLECTION_PROBE_UPDATE_ALWAYS && atlas->reflection.is_valid() && atlas->reflections[0].data.layers[0].mipmaps.size() != 8) {
1422 // Invalidate reflection atlas, need to regenerate
1423 RD::get_singleton()->free(atlas->reflection);
1424 atlas->reflection = RID();
1425
1426 for (int i = 0; i < atlas->reflections.size(); i++) {
1427 if (atlas->reflections[i].owner.is_null()) {
1428 continue;
1429 }
1430 reflection_probe_release_atlas_index(atlas->reflections[i].owner);
1431 }
1432
1433 atlas->reflections.clear();
1434 }
1435
1436 if (atlas->reflection.is_null()) {
1437 int mipmaps = MIN(RendererSceneRenderRD::get_singleton()->get_sky()->roughness_layers, Image::get_image_required_mipmaps(atlas->size, atlas->size, Image::FORMAT_RGBAH) + 1);
1438 mipmaps = LightStorage::get_singleton()->reflection_probe_get_update_mode(rpi->probe) == RS::REFLECTION_PROBE_UPDATE_ALWAYS ? 8 : mipmaps; // always use 8 mipmaps with real time filtering
1439 {
1440 //reflection atlas was unused, create:
1441 RD::TextureFormat tf;
1442 tf.array_layers = 6 * atlas->count;
1443 tf.format = RendererSceneRenderRD::get_singleton()->_render_buffers_get_color_format();
1444 tf.texture_type = RD::TEXTURE_TYPE_CUBE_ARRAY;
1445 tf.mipmaps = mipmaps;
1446 tf.width = atlas->size;
1447 tf.height = atlas->size;
1448 tf.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT | (RendererSceneRenderRD::get_singleton()->_render_buffers_can_be_storage() ? RD::TEXTURE_USAGE_STORAGE_BIT : 0);
1449
1450 atlas->reflection = RD::get_singleton()->texture_create(tf, RD::TextureView());
1451 }
1452 {
1453 RD::TextureFormat tf;
1454 tf.format = RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_D32_SFLOAT, RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) ? RD::DATA_FORMAT_D32_SFLOAT : RD::DATA_FORMAT_X8_D24_UNORM_PACK32;
1455 tf.width = atlas->size;
1456 tf.height = atlas->size;
1457 tf.usage_bits = RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT;
1458 atlas->depth_buffer = RD::get_singleton()->texture_create(tf, RD::TextureView());
1459 }
1460 atlas->reflections.resize(atlas->count);
1461 for (int i = 0; i < atlas->count; i++) {
1462 atlas->reflections.write[i].data.update_reflection_data(atlas->size, mipmaps, false, atlas->reflection, i * 6, LightStorage::get_singleton()->reflection_probe_get_update_mode(rpi->probe) == RS::REFLECTION_PROBE_UPDATE_ALWAYS, RendererSceneRenderRD::get_singleton()->get_sky()->roughness_layers, RendererSceneRenderRD::get_singleton()->_render_buffers_get_color_format());
1463 for (int j = 0; j < 6; j++) {
1464 atlas->reflections.write[i].fbs[j] = RendererSceneRenderRD::get_singleton()->reflection_probe_create_framebuffer(atlas->reflections.write[i].data.layers[0].mipmaps[0].views[j], atlas->depth_buffer);
1465 }
1466 }
1467
1468 Vector<RID> fb;
1469 fb.push_back(atlas->depth_buffer);
1470 atlas->depth_fb = RD::get_singleton()->framebuffer_create(fb);
1471
1472 atlas->render_buffers->configure_for_reflections(Size2i(atlas->size, atlas->size));
1473 }
1474
1475 if (rpi->atlas_index == -1) {
1476 for (int i = 0; i < atlas->reflections.size(); i++) {
1477 if (atlas->reflections[i].owner.is_null()) {
1478 rpi->atlas_index = i;
1479 break;
1480 }
1481 }
1482 //find the one used last
1483 if (rpi->atlas_index == -1) {
1484 //everything is in use, find the one least used via LRU
1485 uint64_t pass_min = 0;
1486
1487 for (int i = 0; i < atlas->reflections.size(); i++) {
1488 ReflectionProbeInstance *rpi2 = reflection_probe_instance_owner.get_or_null(atlas->reflections[i].owner);
1489 if (rpi2->last_pass < pass_min) {
1490 pass_min = rpi2->last_pass;
1491 rpi->atlas_index = i;
1492 }
1493 }
1494 }
1495 }
1496
1497 if (rpi->atlas_index != -1) { // should we fail if this is still -1 ?
1498 atlas->reflections.write[rpi->atlas_index].owner = p_instance;
1499 }
1500
1501 rpi->atlas = p_reflection_atlas;
1502 rpi->rendering = true;
1503 rpi->dirty = false;
1504 rpi->processing_layer = 1;
1505 rpi->processing_side = 0;
1506
1507 RD::get_singleton()->draw_command_end_label();
1508
1509 return true;
1510}
1511
1512Ref<RenderSceneBuffers> LightStorage::reflection_probe_atlas_get_render_buffers(RID p_reflection_atlas) {
1513 ReflectionAtlas *atlas = reflection_atlas_owner.get_or_null(p_reflection_atlas);
1514 ERR_FAIL_COND_V(!atlas, Ref<RenderSceneBuffersRD>());
1515
1516 return atlas->render_buffers;
1517}
1518
1519bool LightStorage::reflection_probe_instance_postprocess_step(RID p_instance) {
1520 ReflectionProbeInstance *rpi = reflection_probe_instance_owner.get_or_null(p_instance);
1521 ERR_FAIL_COND_V(!rpi, false);
1522 ERR_FAIL_COND_V(!rpi->rendering, false);
1523 ERR_FAIL_COND_V(rpi->atlas.is_null(), false);
1524
1525 ReflectionAtlas *atlas = reflection_atlas_owner.get_or_null(rpi->atlas);
1526 if (!atlas || rpi->atlas_index == -1) {
1527 //does not belong to an atlas anymore, cancel (was removed from atlas or atlas changed while rendering)
1528 rpi->rendering = false;
1529 return false;
1530 }
1531
1532 if (LightStorage::get_singleton()->reflection_probe_get_update_mode(rpi->probe) == RS::REFLECTION_PROBE_UPDATE_ALWAYS) {
1533 // Using real time reflections, all roughness is done in one step
1534 atlas->reflections.write[rpi->atlas_index].data.create_reflection_fast_filter(false);
1535 rpi->rendering = false;
1536 rpi->processing_side = 0;
1537 rpi->processing_layer = 1;
1538 return true;
1539 }
1540
1541 if (rpi->processing_layer > 1) {
1542 atlas->reflections.write[rpi->atlas_index].data.create_reflection_importance_sample(false, 10, rpi->processing_layer, RendererSceneRenderRD::get_singleton()->get_sky()->sky_ggx_samples_quality);
1543 rpi->processing_layer++;
1544 if (rpi->processing_layer == atlas->reflections[rpi->atlas_index].data.layers[0].mipmaps.size()) {
1545 rpi->rendering = false;
1546 rpi->processing_side = 0;
1547 rpi->processing_layer = 1;
1548 return true;
1549 }
1550 return false;
1551
1552 } else {
1553 atlas->reflections.write[rpi->atlas_index].data.create_reflection_importance_sample(false, rpi->processing_side, rpi->processing_layer, RendererSceneRenderRD::get_singleton()->get_sky()->sky_ggx_samples_quality);
1554 }
1555
1556 rpi->processing_side++;
1557 if (rpi->processing_side == 6) {
1558 rpi->processing_side = 0;
1559 rpi->processing_layer++;
1560 if (rpi->processing_layer == atlas->reflections[rpi->atlas_index].data.layers[0].mipmaps.size()) {
1561 rpi->rendering = false;
1562 rpi->processing_layer = 1;
1563 return true;
1564 }
1565 }
1566
1567 return false;
1568}
1569
1570uint32_t LightStorage::reflection_probe_instance_get_resolution(RID p_instance) {
1571 ReflectionProbeInstance *rpi = reflection_probe_instance_owner.get_or_null(p_instance);
1572 ERR_FAIL_COND_V(!rpi, 0);
1573
1574 ReflectionAtlas *atlas = reflection_atlas_owner.get_or_null(rpi->atlas);
1575 ERR_FAIL_COND_V(!atlas, 0);
1576 return atlas->size;
1577}
1578
1579RID LightStorage::reflection_probe_instance_get_framebuffer(RID p_instance, int p_index) {
1580 ReflectionProbeInstance *rpi = reflection_probe_instance_owner.get_or_null(p_instance);
1581 ERR_FAIL_COND_V(!rpi, RID());
1582 ERR_FAIL_INDEX_V(p_index, 6, RID());
1583
1584 ReflectionAtlas *atlas = reflection_atlas_owner.get_or_null(rpi->atlas);
1585 ERR_FAIL_COND_V(!atlas, RID());
1586 return atlas->reflections[rpi->atlas_index].fbs[p_index];
1587}
1588
1589RID LightStorage::reflection_probe_instance_get_depth_framebuffer(RID p_instance, int p_index) {
1590 ReflectionProbeInstance *rpi = reflection_probe_instance_owner.get_or_null(p_instance);
1591 ERR_FAIL_COND_V(!rpi, RID());
1592 ERR_FAIL_INDEX_V(p_index, 6, RID());
1593
1594 ReflectionAtlas *atlas = reflection_atlas_owner.get_or_null(rpi->atlas);
1595 ERR_FAIL_COND_V(!atlas, RID());
1596 return atlas->depth_fb;
1597}
1598
1599ClusterBuilderRD *LightStorage::reflection_probe_instance_get_cluster_builder(RID p_instance, ClusterBuilderSharedDataRD *p_cluster_builder_shared) {
1600 ReflectionProbeInstance *rpi = reflection_probe_instance_owner.get_or_null(p_instance);
1601 ReflectionAtlas *ra = reflection_atlas_owner.get_or_null(rpi->atlas);
1602 if (!ra) {
1603 ERR_PRINT("reflection probe has no reflection atlas! Bug?");
1604 return nullptr;
1605 } else {
1606 if (ra->cluster_builder == nullptr) {
1607 ra->cluster_builder = memnew(ClusterBuilderRD);
1608 ra->cluster_builder->set_shared(p_cluster_builder_shared);
1609 ra->cluster_builder->setup(Size2i(ra->size, ra->size), get_max_cluster_elements(), RID(), RID(), RID());
1610 }
1611 return ra->cluster_builder;
1612 }
1613}
1614
1615/* REFLECTION DATA */
1616
1617void LightStorage::free_reflection_data() {
1618 if (reflection_buffer.is_valid()) {
1619 RD::get_singleton()->free(reflection_buffer);
1620 reflection_buffer = RID();
1621 }
1622
1623 if (reflections != nullptr) {
1624 memdelete_arr(reflections);
1625 reflections = nullptr;
1626 }
1627
1628 if (reflection_sort != nullptr) {
1629 memdelete_arr(reflection_sort);
1630 reflection_sort = nullptr;
1631 }
1632}
1633
1634void LightStorage::set_max_reflection_probes(const uint32_t p_max_reflection_probes) {
1635 max_reflections = p_max_reflection_probes;
1636 reflections = memnew_arr(ReflectionData, max_reflections);
1637 reflection_sort = memnew_arr(ReflectionProbeInstanceSort, max_reflections);
1638 reflection_buffer = RD::get_singleton()->storage_buffer_create(sizeof(ReflectionData) * max_reflections);
1639}
1640
1641void LightStorage::update_reflection_probe_buffer(RenderDataRD *p_render_data, const PagedArray<RID> &p_reflections, const Transform3D &p_camera_inverse_transform, RID p_environment) {
1642 ForwardIDStorage *forward_id_storage = ForwardIDStorage::get_singleton();
1643
1644 reflection_count = 0;
1645
1646 for (uint32_t i = 0; i < (uint32_t)p_reflections.size(); i++) {
1647 if (reflection_count == max_reflections) {
1648 break;
1649 }
1650
1651 ReflectionProbeInstance *rpi = reflection_probe_instance_owner.get_or_null(p_reflections[i]);
1652 if (!rpi) {
1653 continue;
1654 }
1655
1656 Transform3D transform = rpi->transform;
1657
1658 reflection_sort[reflection_count].probe_instance = rpi;
1659 reflection_sort[reflection_count].depth = -p_camera_inverse_transform.xform(transform.origin).z;
1660 reflection_count++;
1661 }
1662
1663 if (reflection_count > 0) {
1664 SortArray<ReflectionProbeInstanceSort> sort_array;
1665 sort_array.sort(reflection_sort, reflection_count);
1666 }
1667
1668 bool using_forward_ids = forward_id_storage->uses_forward_ids();
1669 for (uint32_t i = 0; i < reflection_count; i++) {
1670 ReflectionProbeInstance *rpi = reflection_sort[i].probe_instance;
1671
1672 if (using_forward_ids) {
1673 forward_id_storage->map_forward_id(FORWARD_ID_TYPE_REFLECTION_PROBE, rpi->forward_id, i);
1674 }
1675
1676 ReflectionProbe *probe = reflection_probe_owner.get_or_null(rpi->probe);
1677
1678 ReflectionData &reflection_ubo = reflections[i];
1679
1680 Vector3 extents = probe->size / 2;
1681
1682 rpi->cull_mask = probe->cull_mask;
1683
1684 reflection_ubo.box_extents[0] = extents.x;
1685 reflection_ubo.box_extents[1] = extents.y;
1686 reflection_ubo.box_extents[2] = extents.z;
1687 reflection_ubo.index = rpi->atlas_index;
1688
1689 Vector3 origin_offset = probe->origin_offset;
1690
1691 reflection_ubo.box_offset[0] = origin_offset.x;
1692 reflection_ubo.box_offset[1] = origin_offset.y;
1693 reflection_ubo.box_offset[2] = origin_offset.z;
1694 reflection_ubo.mask = probe->cull_mask;
1695
1696 reflection_ubo.intensity = probe->intensity;
1697 reflection_ubo.ambient_mode = probe->ambient_mode;
1698
1699 reflection_ubo.exterior = !probe->interior;
1700 reflection_ubo.box_project = probe->box_projection;
1701 reflection_ubo.exposure_normalization = 1.0;
1702
1703 if (p_render_data->camera_attributes.is_valid()) {
1704 float exposure = RSG::camera_attributes->camera_attributes_get_exposure_normalization_factor(p_render_data->camera_attributes);
1705 reflection_ubo.exposure_normalization = exposure / probe->baked_exposure;
1706 }
1707
1708 Color ambient_linear = probe->ambient_color.srgb_to_linear();
1709 float interior_ambient_energy = probe->ambient_color_energy;
1710 reflection_ubo.ambient[0] = ambient_linear.r * interior_ambient_energy;
1711 reflection_ubo.ambient[1] = ambient_linear.g * interior_ambient_energy;
1712 reflection_ubo.ambient[2] = ambient_linear.b * interior_ambient_energy;
1713
1714 Transform3D transform = rpi->transform;
1715 Transform3D proj = (p_camera_inverse_transform * transform).inverse();
1716 MaterialStorage::store_transform(proj, reflection_ubo.local_matrix);
1717
1718 // hook for subclass to do further processing.
1719 RendererSceneRenderRD::get_singleton()->setup_added_reflection_probe(transform, extents);
1720
1721 rpi->last_pass = RSG::rasterizer->get_frame_number();
1722 }
1723
1724 if (reflection_count) {
1725 RD::get_singleton()->buffer_update(reflection_buffer, 0, reflection_count * sizeof(ReflectionData), reflections, RD::BARRIER_MASK_RASTER | RD::BARRIER_MASK_COMPUTE);
1726 }
1727}
1728
1729/* LIGHTMAP API */
1730
1731RID LightStorage::lightmap_allocate() {
1732 return lightmap_owner.allocate_rid();
1733}
1734
1735void LightStorage::lightmap_initialize(RID p_lightmap) {
1736 lightmap_owner.initialize_rid(p_lightmap, Lightmap());
1737}
1738
1739void LightStorage::lightmap_free(RID p_rid) {
1740 lightmap_set_textures(p_rid, RID(), false);
1741 Lightmap *lightmap = lightmap_owner.get_or_null(p_rid);
1742 lightmap->dependency.deleted_notify(p_rid);
1743 lightmap_owner.free(p_rid);
1744}
1745
1746void LightStorage::lightmap_set_textures(RID p_lightmap, RID p_light, bool p_uses_spherical_haromics) {
1747 TextureStorage *texture_storage = TextureStorage::get_singleton();
1748
1749 Lightmap *lm = lightmap_owner.get_or_null(p_lightmap);
1750 ERR_FAIL_COND(!lm);
1751
1752 lightmap_array_version++;
1753
1754 //erase lightmap users
1755 if (lm->light_texture.is_valid()) {
1756 TextureStorage::Texture *t = texture_storage->get_texture(lm->light_texture);
1757 if (t) {
1758 t->lightmap_users.erase(p_lightmap);
1759 }
1760 }
1761
1762 TextureStorage::Texture *t = texture_storage->get_texture(p_light);
1763 lm->light_texture = p_light;
1764 lm->uses_spherical_harmonics = p_uses_spherical_haromics;
1765
1766 RID default_2d_array = texture_storage->texture_rd_get_default(TextureStorage::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE);
1767 if (!t) {
1768 if (using_lightmap_array) {
1769 if (lm->array_index >= 0) {
1770 lightmap_textures.write[lm->array_index] = default_2d_array;
1771 lm->array_index = -1;
1772 }
1773 }
1774
1775 return;
1776 }
1777
1778 t->lightmap_users.insert(p_lightmap);
1779
1780 if (using_lightmap_array) {
1781 if (lm->array_index < 0) {
1782 //not in array, try to put in array
1783 for (int i = 0; i < lightmap_textures.size(); i++) {
1784 if (lightmap_textures[i] == default_2d_array) {
1785 lm->array_index = i;
1786 break;
1787 }
1788 }
1789 }
1790 ERR_FAIL_COND_MSG(lm->array_index < 0, "Maximum amount of lightmaps in use (" + itos(lightmap_textures.size()) + ") has been exceeded, lightmap will nod display properly.");
1791
1792 lightmap_textures.write[lm->array_index] = t->rd_texture;
1793 }
1794}
1795
1796void LightStorage::lightmap_set_probe_bounds(RID p_lightmap, const AABB &p_bounds) {
1797 Lightmap *lm = lightmap_owner.get_or_null(p_lightmap);
1798 ERR_FAIL_COND(!lm);
1799 lm->bounds = p_bounds;
1800}
1801
1802void LightStorage::lightmap_set_probe_interior(RID p_lightmap, bool p_interior) {
1803 Lightmap *lm = lightmap_owner.get_or_null(p_lightmap);
1804 ERR_FAIL_COND(!lm);
1805 lm->interior = p_interior;
1806}
1807
1808void LightStorage::lightmap_set_probe_capture_data(RID p_lightmap, const PackedVector3Array &p_points, const PackedColorArray &p_point_sh, const PackedInt32Array &p_tetrahedra, const PackedInt32Array &p_bsp_tree) {
1809 Lightmap *lm = lightmap_owner.get_or_null(p_lightmap);
1810 ERR_FAIL_COND(!lm);
1811
1812 if (p_points.size()) {
1813 ERR_FAIL_COND(p_points.size() * 9 != p_point_sh.size());
1814 ERR_FAIL_COND((p_tetrahedra.size() % 4) != 0);
1815 ERR_FAIL_COND((p_bsp_tree.size() % 6) != 0);
1816 }
1817
1818 lm->points = p_points;
1819 lm->bsp_tree = p_bsp_tree;
1820 lm->point_sh = p_point_sh;
1821 lm->tetrahedra = p_tetrahedra;
1822}
1823
1824void LightStorage::lightmap_set_baked_exposure_normalization(RID p_lightmap, float p_exposure) {
1825 Lightmap *lm = lightmap_owner.get_or_null(p_lightmap);
1826 ERR_FAIL_COND(!lm);
1827
1828 lm->baked_exposure = p_exposure;
1829}
1830
1831PackedVector3Array LightStorage::lightmap_get_probe_capture_points(RID p_lightmap) const {
1832 Lightmap *lm = lightmap_owner.get_or_null(p_lightmap);
1833 ERR_FAIL_COND_V(!lm, PackedVector3Array());
1834
1835 return lm->points;
1836}
1837
1838PackedColorArray LightStorage::lightmap_get_probe_capture_sh(RID p_lightmap) const {
1839 Lightmap *lm = lightmap_owner.get_or_null(p_lightmap);
1840 ERR_FAIL_COND_V(!lm, PackedColorArray());
1841 return lm->point_sh;
1842}
1843
1844PackedInt32Array LightStorage::lightmap_get_probe_capture_tetrahedra(RID p_lightmap) const {
1845 Lightmap *lm = lightmap_owner.get_or_null(p_lightmap);
1846 ERR_FAIL_COND_V(!lm, PackedInt32Array());
1847 return lm->tetrahedra;
1848}
1849
1850PackedInt32Array LightStorage::lightmap_get_probe_capture_bsp_tree(RID p_lightmap) const {
1851 Lightmap *lm = lightmap_owner.get_or_null(p_lightmap);
1852 ERR_FAIL_COND_V(!lm, PackedInt32Array());
1853 return lm->bsp_tree;
1854}
1855
1856void LightStorage::lightmap_set_probe_capture_update_speed(float p_speed) {
1857 lightmap_probe_capture_update_speed = p_speed;
1858}
1859
1860Dependency *LightStorage::lightmap_get_dependency(RID p_lightmap) const {
1861 Lightmap *lm = lightmap_owner.get_or_null(p_lightmap);
1862 ERR_FAIL_NULL_V(lm, nullptr);
1863
1864 return &lm->dependency;
1865}
1866
1867void LightStorage::lightmap_tap_sh_light(RID p_lightmap, const Vector3 &p_point, Color *r_sh) {
1868 Lightmap *lm = lightmap_owner.get_or_null(p_lightmap);
1869 ERR_FAIL_COND(!lm);
1870
1871 for (int i = 0; i < 9; i++) {
1872 r_sh[i] = Color(0, 0, 0, 0);
1873 }
1874
1875 if (!lm->points.size() || !lm->bsp_tree.size() || !lm->tetrahedra.size()) {
1876 return;
1877 }
1878
1879 static_assert(sizeof(Lightmap::BSP) == 24);
1880
1881 const Lightmap::BSP *bsp = (const Lightmap::BSP *)lm->bsp_tree.ptr();
1882 int32_t node = 0;
1883 while (node >= 0) {
1884 if (Plane(bsp[node].plane[0], bsp[node].plane[1], bsp[node].plane[2], bsp[node].plane[3]).is_point_over(p_point)) {
1885#ifdef DEBUG_ENABLED
1886 ERR_FAIL_COND(bsp[node].over >= 0 && bsp[node].over < node);
1887#endif
1888
1889 node = bsp[node].over;
1890 } else {
1891#ifdef DEBUG_ENABLED
1892 ERR_FAIL_COND(bsp[node].under >= 0 && bsp[node].under < node);
1893#endif
1894 node = bsp[node].under;
1895 }
1896 }
1897
1898 if (node == Lightmap::BSP::EMPTY_LEAF) {
1899 return; //nothing could be done
1900 }
1901
1902 node = ABS(node) - 1;
1903
1904 uint32_t *tetrahedron = (uint32_t *)&lm->tetrahedra[node * 4];
1905 Vector3 points[4] = { lm->points[tetrahedron[0]], lm->points[tetrahedron[1]], lm->points[tetrahedron[2]], lm->points[tetrahedron[3]] };
1906 const Color *sh_colors[4]{ &lm->point_sh[tetrahedron[0] * 9], &lm->point_sh[tetrahedron[1] * 9], &lm->point_sh[tetrahedron[2] * 9], &lm->point_sh[tetrahedron[3] * 9] };
1907 Color barycentric = Geometry3D::tetrahedron_get_barycentric_coords(points[0], points[1], points[2], points[3], p_point);
1908
1909 for (int i = 0; i < 4; i++) {
1910 float c = CLAMP(barycentric[i], 0.0, 1.0);
1911 for (int j = 0; j < 9; j++) {
1912 r_sh[j] += sh_colors[i][j] * c;
1913 }
1914 }
1915}
1916
1917bool LightStorage::lightmap_is_interior(RID p_lightmap) const {
1918 const Lightmap *lm = lightmap_owner.get_or_null(p_lightmap);
1919 ERR_FAIL_COND_V(!lm, false);
1920 return lm->interior;
1921}
1922
1923AABB LightStorage::lightmap_get_aabb(RID p_lightmap) const {
1924 const Lightmap *lm = lightmap_owner.get_or_null(p_lightmap);
1925 ERR_FAIL_COND_V(!lm, AABB());
1926 return lm->bounds;
1927}
1928
1929/* LIGHTMAP INSTANCE */
1930
1931RID LightStorage::lightmap_instance_create(RID p_lightmap) {
1932 LightmapInstance li;
1933 li.lightmap = p_lightmap;
1934 return lightmap_instance_owner.make_rid(li);
1935}
1936
1937void LightStorage::lightmap_instance_free(RID p_lightmap) {
1938 lightmap_instance_owner.free(p_lightmap);
1939}
1940
1941void LightStorage::lightmap_instance_set_transform(RID p_lightmap, const Transform3D &p_transform) {
1942 LightmapInstance *li = lightmap_instance_owner.get_or_null(p_lightmap);
1943 ERR_FAIL_COND(!li);
1944 li->transform = p_transform;
1945}
1946
1947/* SHADOW ATLAS API */
1948
1949RID LightStorage::shadow_atlas_create() {
1950 return shadow_atlas_owner.make_rid(ShadowAtlas());
1951}
1952
1953void LightStorage::shadow_atlas_free(RID p_atlas) {
1954 shadow_atlas_set_size(p_atlas, 0);
1955 shadow_atlas_owner.free(p_atlas);
1956}
1957
1958void LightStorage::_update_shadow_atlas(ShadowAtlas *shadow_atlas) {
1959 if (shadow_atlas->size > 0 && shadow_atlas->depth.is_null()) {
1960 RD::TextureFormat tf;
1961 tf.format = shadow_atlas->use_16_bits ? RD::DATA_FORMAT_D16_UNORM : RD::DATA_FORMAT_D32_SFLOAT;
1962 tf.width = shadow_atlas->size;
1963 tf.height = shadow_atlas->size;
1964 tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
1965
1966 shadow_atlas->depth = RD::get_singleton()->texture_create(tf, RD::TextureView());
1967 Vector<RID> fb_tex;
1968 fb_tex.push_back(shadow_atlas->depth);
1969 shadow_atlas->fb = RD::get_singleton()->framebuffer_create(fb_tex);
1970 }
1971}
1972
1973void LightStorage::shadow_atlas_set_size(RID p_atlas, int p_size, bool p_16_bits) {
1974 ShadowAtlas *shadow_atlas = shadow_atlas_owner.get_or_null(p_atlas);
1975 ERR_FAIL_COND(!shadow_atlas);
1976 ERR_FAIL_COND(p_size < 0);
1977 p_size = next_power_of_2(p_size);
1978
1979 if (p_size == shadow_atlas->size && p_16_bits == shadow_atlas->use_16_bits) {
1980 return;
1981 }
1982
1983 // erasing atlas
1984 if (shadow_atlas->depth.is_valid()) {
1985 RD::get_singleton()->free(shadow_atlas->depth);
1986 shadow_atlas->depth = RID();
1987 }
1988 for (int i = 0; i < 4; i++) {
1989 //clear subdivisions
1990 shadow_atlas->quadrants[i].shadows.clear();
1991 shadow_atlas->quadrants[i].shadows.resize(1 << shadow_atlas->quadrants[i].subdivision);
1992 }
1993
1994 //erase shadow atlas reference from lights
1995 for (const KeyValue<RID, uint32_t> &E : shadow_atlas->shadow_owners) {
1996 LightInstance *li = light_instance_owner.get_or_null(E.key);
1997 ERR_CONTINUE(!li);
1998 li->shadow_atlases.erase(p_atlas);
1999 }
2000
2001 //clear owners
2002 shadow_atlas->shadow_owners.clear();
2003
2004 shadow_atlas->size = p_size;
2005 shadow_atlas->use_16_bits = p_16_bits;
2006}
2007
2008void LightStorage::shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p_quadrant, int p_subdivision) {
2009 ShadowAtlas *shadow_atlas = shadow_atlas_owner.get_or_null(p_atlas);
2010 ERR_FAIL_COND(!shadow_atlas);
2011 ERR_FAIL_INDEX(p_quadrant, 4);
2012 ERR_FAIL_INDEX(p_subdivision, 16384);
2013
2014 uint32_t subdiv = next_power_of_2(p_subdivision);
2015 if (subdiv & 0xaaaaaaaa) { //sqrt(subdiv) must be integer
2016 subdiv <<= 1;
2017 }
2018
2019 subdiv = int(Math::sqrt((float)subdiv));
2020
2021 //obtain the number that will be x*x
2022
2023 if (shadow_atlas->quadrants[p_quadrant].subdivision == subdiv) {
2024 return;
2025 }
2026
2027 //erase all data from quadrant
2028 for (int i = 0; i < shadow_atlas->quadrants[p_quadrant].shadows.size(); i++) {
2029 if (shadow_atlas->quadrants[p_quadrant].shadows[i].owner.is_valid()) {
2030 shadow_atlas->shadow_owners.erase(shadow_atlas->quadrants[p_quadrant].shadows[i].owner);
2031 LightInstance *li = light_instance_owner.get_or_null(shadow_atlas->quadrants[p_quadrant].shadows[i].owner);
2032 ERR_CONTINUE(!li);
2033 li->shadow_atlases.erase(p_atlas);
2034 }
2035 }
2036
2037 shadow_atlas->quadrants[p_quadrant].shadows.clear();
2038 shadow_atlas->quadrants[p_quadrant].shadows.resize(subdiv * subdiv);
2039 shadow_atlas->quadrants[p_quadrant].subdivision = subdiv;
2040
2041 //cache the smallest subdiv (for faster allocation in light update)
2042
2043 shadow_atlas->smallest_subdiv = 1 << 30;
2044
2045 for (int i = 0; i < 4; i++) {
2046 if (shadow_atlas->quadrants[i].subdivision) {
2047 shadow_atlas->smallest_subdiv = MIN(shadow_atlas->smallest_subdiv, shadow_atlas->quadrants[i].subdivision);
2048 }
2049 }
2050
2051 if (shadow_atlas->smallest_subdiv == 1 << 30) {
2052 shadow_atlas->smallest_subdiv = 0;
2053 }
2054
2055 //resort the size orders, simple bublesort for 4 elements..
2056
2057 int swaps = 0;
2058 do {
2059 swaps = 0;
2060
2061 for (int i = 0; i < 3; i++) {
2062 if (shadow_atlas->quadrants[shadow_atlas->size_order[i]].subdivision < shadow_atlas->quadrants[shadow_atlas->size_order[i + 1]].subdivision) {
2063 SWAP(shadow_atlas->size_order[i], shadow_atlas->size_order[i + 1]);
2064 swaps++;
2065 }
2066 }
2067 } while (swaps > 0);
2068}
2069
2070bool LightStorage::_shadow_atlas_find_shadow(ShadowAtlas *shadow_atlas, int *p_in_quadrants, int p_quadrant_count, int p_current_subdiv, uint64_t p_tick, int &r_quadrant, int &r_shadow) {
2071 for (int i = p_quadrant_count - 1; i >= 0; i--) {
2072 int qidx = p_in_quadrants[i];
2073
2074 if (shadow_atlas->quadrants[qidx].subdivision == (uint32_t)p_current_subdiv) {
2075 return false;
2076 }
2077
2078 //look for an empty space
2079 int sc = shadow_atlas->quadrants[qidx].shadows.size();
2080 const ShadowAtlas::Quadrant::Shadow *sarr = shadow_atlas->quadrants[qidx].shadows.ptr();
2081
2082 int found_free_idx = -1; //found a free one
2083 int found_used_idx = -1; //found existing one, must steal it
2084 uint64_t min_pass = 0; // pass of the existing one, try to use the least recently used one (LRU fashion)
2085
2086 for (int j = 0; j < sc; j++) {
2087 if (!sarr[j].owner.is_valid()) {
2088 found_free_idx = j;
2089 break;
2090 }
2091
2092 LightInstance *sli = light_instance_owner.get_or_null(sarr[j].owner);
2093 ERR_CONTINUE(!sli);
2094
2095 if (sli->last_scene_pass != RendererSceneRenderRD::get_singleton()->get_scene_pass()) {
2096 //was just allocated, don't kill it so soon, wait a bit..
2097 if (p_tick - sarr[j].alloc_tick < shadow_atlas_realloc_tolerance_msec) {
2098 continue;
2099 }
2100
2101 if (found_used_idx == -1 || sli->last_scene_pass < min_pass) {
2102 found_used_idx = j;
2103 min_pass = sli->last_scene_pass;
2104 }
2105 }
2106 }
2107
2108 if (found_free_idx == -1 && found_used_idx == -1) {
2109 continue; //nothing found
2110 }
2111
2112 if (found_free_idx == -1 && found_used_idx != -1) {
2113 found_free_idx = found_used_idx;
2114 }
2115
2116 r_quadrant = qidx;
2117 r_shadow = found_free_idx;
2118
2119 return true;
2120 }
2121
2122 return false;
2123}
2124
2125bool LightStorage::_shadow_atlas_find_omni_shadows(ShadowAtlas *shadow_atlas, int *p_in_quadrants, int p_quadrant_count, int p_current_subdiv, uint64_t p_tick, int &r_quadrant, int &r_shadow) {
2126 for (int i = p_quadrant_count - 1; i >= 0; i--) {
2127 int qidx = p_in_quadrants[i];
2128
2129 if (shadow_atlas->quadrants[qidx].subdivision == (uint32_t)p_current_subdiv) {
2130 return false;
2131 }
2132
2133 //look for an empty space
2134 int sc = shadow_atlas->quadrants[qidx].shadows.size();
2135 const ShadowAtlas::Quadrant::Shadow *sarr = shadow_atlas->quadrants[qidx].shadows.ptr();
2136
2137 int found_idx = -1;
2138 uint64_t min_pass = 0; // sum of currently selected spots, try to get the least recently used pair
2139
2140 for (int j = 0; j < sc - 1; j++) {
2141 uint64_t pass = 0;
2142
2143 if (sarr[j].owner.is_valid()) {
2144 LightInstance *sli = light_instance_owner.get_or_null(sarr[j].owner);
2145 ERR_CONTINUE(!sli);
2146
2147 if (sli->last_scene_pass == RendererSceneRenderRD::get_singleton()->get_scene_pass()) {
2148 continue;
2149 }
2150
2151 //was just allocated, don't kill it so soon, wait a bit..
2152 if (p_tick - sarr[j].alloc_tick < shadow_atlas_realloc_tolerance_msec) {
2153 continue;
2154 }
2155 pass += sli->last_scene_pass;
2156 }
2157
2158 if (sarr[j + 1].owner.is_valid()) {
2159 LightInstance *sli = light_instance_owner.get_or_null(sarr[j + 1].owner);
2160 ERR_CONTINUE(!sli);
2161
2162 if (sli->last_scene_pass == RendererSceneRenderRD::get_singleton()->get_scene_pass()) {
2163 continue;
2164 }
2165
2166 //was just allocated, don't kill it so soon, wait a bit..
2167 if (p_tick - sarr[j + 1].alloc_tick < shadow_atlas_realloc_tolerance_msec) {
2168 continue;
2169 }
2170 pass += sli->last_scene_pass;
2171 }
2172
2173 if (found_idx == -1 || pass < min_pass) {
2174 found_idx = j;
2175 min_pass = pass;
2176
2177 // we found two empty spots, no need to check the rest
2178 if (pass == 0) {
2179 break;
2180 }
2181 }
2182 }
2183
2184 if (found_idx == -1) {
2185 continue; //nothing found
2186 }
2187
2188 r_quadrant = qidx;
2189 r_shadow = found_idx;
2190
2191 return true;
2192 }
2193
2194 return false;
2195}
2196
2197bool LightStorage::shadow_atlas_update_light(RID p_atlas, RID p_light_instance, float p_coverage, uint64_t p_light_version) {
2198 ShadowAtlas *shadow_atlas = shadow_atlas_owner.get_or_null(p_atlas);
2199 ERR_FAIL_COND_V(!shadow_atlas, false);
2200
2201 LightInstance *li = light_instance_owner.get_or_null(p_light_instance);
2202 ERR_FAIL_COND_V(!li, false);
2203
2204 if (shadow_atlas->size == 0 || shadow_atlas->smallest_subdiv == 0) {
2205 return false;
2206 }
2207
2208 uint32_t quad_size = shadow_atlas->size >> 1;
2209 int desired_fit = MIN(quad_size / shadow_atlas->smallest_subdiv, next_power_of_2(quad_size * p_coverage));
2210
2211 int valid_quadrants[4];
2212 int valid_quadrant_count = 0;
2213 int best_size = -1; //best size found
2214 int best_subdiv = -1; //subdiv for the best size
2215
2216 //find the quadrants this fits into, and the best possible size it can fit into
2217 for (int i = 0; i < 4; i++) {
2218 int q = shadow_atlas->size_order[i];
2219 int sd = shadow_atlas->quadrants[q].subdivision;
2220 if (sd == 0) {
2221 continue; //unused
2222 }
2223
2224 int max_fit = quad_size / sd;
2225
2226 if (best_size != -1 && max_fit > best_size) {
2227 break; //too large
2228 }
2229
2230 valid_quadrants[valid_quadrant_count++] = q;
2231 best_subdiv = sd;
2232
2233 if (max_fit >= desired_fit) {
2234 best_size = max_fit;
2235 }
2236 }
2237
2238 ERR_FAIL_COND_V(valid_quadrant_count == 0, false);
2239
2240 uint64_t tick = OS::get_singleton()->get_ticks_msec();
2241
2242 uint32_t old_key = SHADOW_INVALID;
2243 uint32_t old_quadrant = SHADOW_INVALID;
2244 uint32_t old_shadow = SHADOW_INVALID;
2245 int old_subdivision = -1;
2246
2247 bool should_realloc = false;
2248 bool should_redraw = false;
2249
2250 if (shadow_atlas->shadow_owners.has(p_light_instance)) {
2251 old_key = shadow_atlas->shadow_owners[p_light_instance];
2252 old_quadrant = (old_key >> QUADRANT_SHIFT) & 0x3;
2253 old_shadow = old_key & SHADOW_INDEX_MASK;
2254
2255 should_realloc = shadow_atlas->quadrants[old_quadrant].subdivision != (uint32_t)best_subdiv && (shadow_atlas->quadrants[old_quadrant].shadows[old_shadow].alloc_tick - tick > shadow_atlas_realloc_tolerance_msec);
2256 should_redraw = shadow_atlas->quadrants[old_quadrant].shadows[old_shadow].version != p_light_version;
2257
2258 if (!should_realloc) {
2259 shadow_atlas->quadrants[old_quadrant].shadows.write[old_shadow].version = p_light_version;
2260 //already existing, see if it should redraw or it's just OK
2261 return should_redraw;
2262 }
2263
2264 old_subdivision = shadow_atlas->quadrants[old_quadrant].subdivision;
2265 }
2266
2267 bool is_omni = li->light_type == RS::LIGHT_OMNI;
2268 bool found_shadow = false;
2269 int new_quadrant = -1;
2270 int new_shadow = -1;
2271
2272 if (is_omni) {
2273 found_shadow = _shadow_atlas_find_omni_shadows(shadow_atlas, valid_quadrants, valid_quadrant_count, old_subdivision, tick, new_quadrant, new_shadow);
2274 } else {
2275 found_shadow = _shadow_atlas_find_shadow(shadow_atlas, valid_quadrants, valid_quadrant_count, old_subdivision, tick, new_quadrant, new_shadow);
2276 }
2277
2278 if (found_shadow) {
2279 if (old_quadrant != SHADOW_INVALID) {
2280 shadow_atlas->quadrants[old_quadrant].shadows.write[old_shadow].version = 0;
2281 shadow_atlas->quadrants[old_quadrant].shadows.write[old_shadow].owner = RID();
2282
2283 if (old_key & OMNI_LIGHT_FLAG) {
2284 shadow_atlas->quadrants[old_quadrant].shadows.write[old_shadow + 1].version = 0;
2285 shadow_atlas->quadrants[old_quadrant].shadows.write[old_shadow + 1].owner = RID();
2286 }
2287 }
2288
2289 uint32_t new_key = new_quadrant << QUADRANT_SHIFT;
2290 new_key |= new_shadow;
2291
2292 ShadowAtlas::Quadrant::Shadow *sh = &shadow_atlas->quadrants[new_quadrant].shadows.write[new_shadow];
2293 _shadow_atlas_invalidate_shadow(sh, p_atlas, shadow_atlas, new_quadrant, new_shadow);
2294
2295 sh->owner = p_light_instance;
2296 sh->alloc_tick = tick;
2297 sh->version = p_light_version;
2298
2299 if (is_omni) {
2300 new_key |= OMNI_LIGHT_FLAG;
2301
2302 int new_omni_shadow = new_shadow + 1;
2303 ShadowAtlas::Quadrant::Shadow *extra_sh = &shadow_atlas->quadrants[new_quadrant].shadows.write[new_omni_shadow];
2304 _shadow_atlas_invalidate_shadow(extra_sh, p_atlas, shadow_atlas, new_quadrant, new_omni_shadow);
2305
2306 extra_sh->owner = p_light_instance;
2307 extra_sh->alloc_tick = tick;
2308 extra_sh->version = p_light_version;
2309 }
2310
2311 li->shadow_atlases.insert(p_atlas);
2312
2313 //update it in map
2314 shadow_atlas->shadow_owners[p_light_instance] = new_key;
2315 //make it dirty, as it should redraw anyway
2316 return true;
2317 }
2318
2319 return should_redraw;
2320}
2321
2322void LightStorage::_shadow_atlas_invalidate_shadow(ShadowAtlas::Quadrant::Shadow *p_shadow, RID p_atlas, ShadowAtlas *p_shadow_atlas, uint32_t p_quadrant, uint32_t p_shadow_idx) {
2323 if (p_shadow->owner.is_valid()) {
2324 LightInstance *sli = light_instance_owner.get_or_null(p_shadow->owner);
2325 uint32_t old_key = p_shadow_atlas->shadow_owners[p_shadow->owner];
2326
2327 if (old_key & OMNI_LIGHT_FLAG) {
2328 uint32_t s = old_key & SHADOW_INDEX_MASK;
2329 uint32_t omni_shadow_idx = p_shadow_idx + (s == (uint32_t)p_shadow_idx ? 1 : -1);
2330 ShadowAtlas::Quadrant::Shadow *omni_shadow = &p_shadow_atlas->quadrants[p_quadrant].shadows.write[omni_shadow_idx];
2331 omni_shadow->version = 0;
2332 omni_shadow->owner = RID();
2333 }
2334
2335 p_shadow_atlas->shadow_owners.erase(p_shadow->owner);
2336 p_shadow->version = 0;
2337 p_shadow->owner = RID();
2338 sli->shadow_atlases.erase(p_atlas);
2339 }
2340}
2341
2342void LightStorage::shadow_atlas_update(RID p_atlas) {
2343 ShadowAtlas *shadow_atlas = shadow_atlas_owner.get_or_null(p_atlas);
2344 ERR_FAIL_COND(!shadow_atlas);
2345
2346 _update_shadow_atlas(shadow_atlas);
2347}
2348
2349/* DIRECTIONAL SHADOW */
2350
2351void LightStorage::update_directional_shadow_atlas() {
2352 if (directional_shadow.depth.is_null() && directional_shadow.size > 0) {
2353 RD::TextureFormat tf;
2354 tf.format = directional_shadow.use_16_bits ? RD::DATA_FORMAT_D16_UNORM : RD::DATA_FORMAT_D32_SFLOAT;
2355 tf.width = directional_shadow.size;
2356 tf.height = directional_shadow.size;
2357 tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
2358
2359 directional_shadow.depth = RD::get_singleton()->texture_create(tf, RD::TextureView());
2360 Vector<RID> fb_tex;
2361 fb_tex.push_back(directional_shadow.depth);
2362 directional_shadow.fb = RD::get_singleton()->framebuffer_create(fb_tex);
2363 }
2364}
2365void LightStorage::directional_shadow_atlas_set_size(int p_size, bool p_16_bits) {
2366 p_size = nearest_power_of_2_templated(p_size);
2367
2368 if (directional_shadow.size == p_size && directional_shadow.use_16_bits == p_16_bits) {
2369 return;
2370 }
2371
2372 directional_shadow.size = p_size;
2373 directional_shadow.use_16_bits = p_16_bits;
2374
2375 if (directional_shadow.depth.is_valid()) {
2376 RD::get_singleton()->free(directional_shadow.depth);
2377 directional_shadow.depth = RID();
2378 RendererSceneRenderRD::get_singleton()->base_uniforms_changed();
2379 }
2380}
2381
2382void LightStorage::set_directional_shadow_count(int p_count) {
2383 directional_shadow.light_count = p_count;
2384 directional_shadow.current_light = 0;
2385}
2386
2387static Rect2i _get_directional_shadow_rect(int p_size, int p_shadow_count, int p_shadow_index) {
2388 int split_h = 1;
2389 int split_v = 1;
2390
2391 while (split_h * split_v < p_shadow_count) {
2392 if (split_h == split_v) {
2393 split_h <<= 1;
2394 } else {
2395 split_v <<= 1;
2396 }
2397 }
2398
2399 Rect2i rect(0, 0, p_size, p_size);
2400 rect.size.width /= split_h;
2401 rect.size.height /= split_v;
2402
2403 rect.position.x = rect.size.width * (p_shadow_index % split_h);
2404 rect.position.y = rect.size.height * (p_shadow_index / split_h);
2405
2406 return rect;
2407}
2408
2409Rect2i LightStorage::get_directional_shadow_rect() {
2410 return _get_directional_shadow_rect(directional_shadow.size, directional_shadow.light_count, directional_shadow.current_light);
2411}
2412
2413int LightStorage::get_directional_light_shadow_size(RID p_light_intance) {
2414 ERR_FAIL_COND_V(directional_shadow.light_count == 0, 0);
2415
2416 Rect2i r = _get_directional_shadow_rect(directional_shadow.size, directional_shadow.light_count, 0);
2417
2418 LightInstance *light_instance = light_instance_owner.get_or_null(p_light_intance);
2419 ERR_FAIL_COND_V(!light_instance, 0);
2420
2421 switch (light_directional_get_shadow_mode(light_instance->light)) {
2422 case RS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL:
2423 break; //none
2424 case RS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS:
2425 r.size.height /= 2;
2426 break;
2427 case RS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_4_SPLITS:
2428 r.size /= 2;
2429 break;
2430 }
2431
2432 return MAX(r.size.width, r.size.height);
2433}
2434
2435/* SHADOW CUBEMAPS */
2436
2437LightStorage::ShadowCubemap *LightStorage::_get_shadow_cubemap(int p_size) {
2438 if (!shadow_cubemaps.has(p_size)) {
2439 ShadowCubemap sc;
2440 {
2441 RD::TextureFormat tf;
2442 tf.format = RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_D32_SFLOAT, RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) ? RD::DATA_FORMAT_D32_SFLOAT : RD::DATA_FORMAT_X8_D24_UNORM_PACK32;
2443 tf.width = p_size;
2444 tf.height = p_size;
2445 tf.texture_type = RD::TEXTURE_TYPE_CUBE;
2446 tf.array_layers = 6;
2447 tf.usage_bits = RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT;
2448 sc.cubemap = RD::get_singleton()->texture_create(tf, RD::TextureView());
2449 }
2450
2451 for (int i = 0; i < 6; i++) {
2452 RID side_texture = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), sc.cubemap, i, 0);
2453 Vector<RID> fbtex;
2454 fbtex.push_back(side_texture);
2455 sc.side_fb[i] = RD::get_singleton()->framebuffer_create(fbtex);
2456 }
2457
2458 shadow_cubemaps[p_size] = sc;
2459 }
2460
2461 return &shadow_cubemaps[p_size];
2462}
2463
2464RID LightStorage::get_cubemap(int p_size) {
2465 ShadowCubemap *cubemap = _get_shadow_cubemap(p_size);
2466
2467 return cubemap->cubemap;
2468}
2469
2470RID LightStorage::get_cubemap_fb(int p_size, int p_pass) {
2471 ShadowCubemap *cubemap = _get_shadow_cubemap(p_size);
2472
2473 return cubemap->side_fb[p_pass];
2474}
2475