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 | |
36 | using namespace RendererRD; |
37 | |
38 | LightStorage *LightStorage::singleton = nullptr; |
39 | |
40 | LightStorage *LightStorage::get_singleton() { |
41 | return singleton; |
42 | } |
43 | |
44 | LightStorage::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 | |
70 | LightStorage::~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 | |
81 | bool 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 | |
113 | void 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 | |
142 | RID LightStorage::directional_light_allocate() { |
143 | return light_owner.allocate_rid(); |
144 | } |
145 | |
146 | void LightStorage::directional_light_initialize(RID p_light) { |
147 | _light_initialize(p_light, RS::LIGHT_DIRECTIONAL); |
148 | } |
149 | |
150 | RID LightStorage::omni_light_allocate() { |
151 | return light_owner.allocate_rid(); |
152 | } |
153 | |
154 | void LightStorage::omni_light_initialize(RID p_light) { |
155 | _light_initialize(p_light, RS::LIGHT_OMNI); |
156 | } |
157 | |
158 | RID LightStorage::spot_light_allocate() { |
159 | return light_owner.allocate_rid(); |
160 | } |
161 | |
162 | void LightStorage::spot_light_initialize(RID p_light) { |
163 | _light_initialize(p_light, RS::LIGHT_SPOT); |
164 | } |
165 | |
166 | void 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 | |
175 | void 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 | |
182 | void 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 | |
217 | void 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 | |
226 | void 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 | |
251 | void 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 | |
258 | void 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 | |
268 | void 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 | |
278 | void 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 | |
288 | void 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 | |
298 | void 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 | |
308 | void 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 | |
318 | RS::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 | |
325 | void 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 | |
334 | void 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 | |
343 | bool 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 | |
350 | void 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 | |
357 | RS::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 | |
364 | RS::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 | |
371 | uint32_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 | |
378 | RS::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 | |
385 | uint64_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 | |
392 | uint32_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 | |
399 | AABB 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 | |
421 | Dependency *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 | |
430 | RID 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 | |
445 | void 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 | |
472 | void 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 | |
479 | void 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 | |
486 | void 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 | |
502 | void 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 | |
511 | void 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 | |
553 | void 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 | |
571 | void 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 | |
1013 | RID LightStorage::reflection_probe_allocate() { |
1014 | return reflection_probe_owner.allocate_rid(); |
1015 | } |
1016 | |
1017 | void LightStorage::reflection_probe_initialize(RID p_reflection_probe) { |
1018 | reflection_probe_owner.initialize_rid(p_reflection_probe, ReflectionProbe()); |
1019 | } |
1020 | |
1021 | void 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 | |
1027 | void 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 | |
1035 | void 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 | |
1042 | void 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 | |
1049 | void 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 | |
1056 | void 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 | |
1063 | void 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 | |
1072 | void 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 | |
1083 | void 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 | |
1091 | void 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 | |
1099 | void 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 | |
1106 | void 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 | |
1114 | void 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 | |
1122 | void 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 | |
1130 | void 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 | |
1139 | void 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 | |
1146 | AABB 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 | |
1157 | RS::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 | |
1164 | uint32_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 | |
1171 | Vector3 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 | |
1178 | Vector3 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 | |
1185 | bool 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 | |
1192 | float 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 | |
1199 | float 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 | |
1206 | int 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 | |
1213 | float 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 | |
1220 | float 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 | |
1227 | bool 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 | |
1234 | bool 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 | |
1241 | RS::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 | |
1247 | Color 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 | } |
1253 | float 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 | |
1260 | Dependency *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 | |
1269 | RID 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 | |
1278 | void 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 | |
1287 | void 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 | |
1326 | int 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 | |
1335 | RID 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 | |
1343 | void 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 | |
1350 | void 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 | |
1358 | void 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 | |
1376 | bool 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 | |
1395 | bool 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 | |
1402 | bool 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 | |
1512 | Ref<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 | |
1519 | bool 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 | |
1570 | uint32_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 | |
1579 | RID 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 | |
1589 | RID 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 | |
1599 | ClusterBuilderRD *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 | |
1617 | void 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 | |
1634 | void 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 | |
1641 | void 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 | |
1731 | RID LightStorage::lightmap_allocate() { |
1732 | return lightmap_owner.allocate_rid(); |
1733 | } |
1734 | |
1735 | void LightStorage::lightmap_initialize(RID p_lightmap) { |
1736 | lightmap_owner.initialize_rid(p_lightmap, Lightmap()); |
1737 | } |
1738 | |
1739 | void 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 | |
1746 | void 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 | |
1796 | void 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 | |
1802 | void 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 | |
1808 | void 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 | |
1824 | void 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 | |
1831 | PackedVector3Array 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 | |
1838 | PackedColorArray 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 | |
1844 | PackedInt32Array 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 | |
1850 | PackedInt32Array 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 | |
1856 | void LightStorage::lightmap_set_probe_capture_update_speed(float p_speed) { |
1857 | lightmap_probe_capture_update_speed = p_speed; |
1858 | } |
1859 | |
1860 | Dependency *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 | |
1867 | void 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 | |
1917 | bool 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 | |
1923 | AABB 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 | |
1931 | RID 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 | |
1937 | void LightStorage::lightmap_instance_free(RID p_lightmap) { |
1938 | lightmap_instance_owner.free(p_lightmap); |
1939 | } |
1940 | |
1941 | void 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 | |
1949 | RID LightStorage::shadow_atlas_create() { |
1950 | return shadow_atlas_owner.make_rid(ShadowAtlas()); |
1951 | } |
1952 | |
1953 | void LightStorage::shadow_atlas_free(RID p_atlas) { |
1954 | shadow_atlas_set_size(p_atlas, 0); |
1955 | shadow_atlas_owner.free(p_atlas); |
1956 | } |
1957 | |
1958 | void 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 | |
1973 | void 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 | |
2008 | void 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 | |
2070 | bool 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 | |
2125 | bool 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 | |
2197 | bool 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 * = &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 | |
2322 | void 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 | |
2342 | void 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 | |
2351 | void 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 | } |
2365 | void 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 | |
2382 | void LightStorage::set_directional_shadow_count(int p_count) { |
2383 | directional_shadow.light_count = p_count; |
2384 | directional_shadow.current_light = 0; |
2385 | } |
2386 | |
2387 | static 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 | |
2409 | Rect2i LightStorage::get_directional_shadow_rect() { |
2410 | return _get_directional_shadow_rect(directional_shadow.size, directional_shadow.light_count, directional_shadow.current_light); |
2411 | } |
2412 | |
2413 | int 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 | |
2437 | LightStorage::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 | |
2464 | RID LightStorage::get_cubemap(int p_size) { |
2465 | ShadowCubemap *cubemap = _get_shadow_cubemap(p_size); |
2466 | |
2467 | return cubemap->cubemap; |
2468 | } |
2469 | |
2470 | RID 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 | |