1/**************************************************************************/
2/* renderer_scene_cull.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 "renderer_scene_cull.h"
32
33#include "core/config/project_settings.h"
34#include "core/object/worker_thread_pool.h"
35#include "core/os/os.h"
36#include "rendering_server_default.h"
37
38#include <new>
39
40/* CAMERA API */
41
42RID RendererSceneCull::camera_allocate() {
43 return camera_owner.allocate_rid();
44}
45void RendererSceneCull::camera_initialize(RID p_rid) {
46 camera_owner.initialize_rid(p_rid);
47}
48
49void RendererSceneCull::camera_set_perspective(RID p_camera, float p_fovy_degrees, float p_z_near, float p_z_far) {
50 Camera *camera = camera_owner.get_or_null(p_camera);
51 ERR_FAIL_COND(!camera);
52 camera->type = Camera::PERSPECTIVE;
53 camera->fov = p_fovy_degrees;
54 camera->znear = p_z_near;
55 camera->zfar = p_z_far;
56}
57
58void RendererSceneCull::camera_set_orthogonal(RID p_camera, float p_size, float p_z_near, float p_z_far) {
59 Camera *camera = camera_owner.get_or_null(p_camera);
60 ERR_FAIL_COND(!camera);
61 camera->type = Camera::ORTHOGONAL;
62 camera->size = p_size;
63 camera->znear = p_z_near;
64 camera->zfar = p_z_far;
65}
66
67void RendererSceneCull::camera_set_frustum(RID p_camera, float p_size, Vector2 p_offset, float p_z_near, float p_z_far) {
68 Camera *camera = camera_owner.get_or_null(p_camera);
69 ERR_FAIL_COND(!camera);
70 camera->type = Camera::FRUSTUM;
71 camera->size = p_size;
72 camera->offset = p_offset;
73 camera->znear = p_z_near;
74 camera->zfar = p_z_far;
75}
76
77void RendererSceneCull::camera_set_transform(RID p_camera, const Transform3D &p_transform) {
78 Camera *camera = camera_owner.get_or_null(p_camera);
79 ERR_FAIL_COND(!camera);
80 camera->transform = p_transform.orthonormalized();
81}
82
83void RendererSceneCull::camera_set_cull_mask(RID p_camera, uint32_t p_layers) {
84 Camera *camera = camera_owner.get_or_null(p_camera);
85 ERR_FAIL_COND(!camera);
86
87 camera->visible_layers = p_layers;
88}
89
90void RendererSceneCull::camera_set_environment(RID p_camera, RID p_env) {
91 Camera *camera = camera_owner.get_or_null(p_camera);
92 ERR_FAIL_COND(!camera);
93 camera->env = p_env;
94}
95
96void RendererSceneCull::camera_set_camera_attributes(RID p_camera, RID p_attributes) {
97 Camera *camera = camera_owner.get_or_null(p_camera);
98 ERR_FAIL_COND(!camera);
99 camera->attributes = p_attributes;
100}
101
102void RendererSceneCull::camera_set_use_vertical_aspect(RID p_camera, bool p_enable) {
103 Camera *camera = camera_owner.get_or_null(p_camera);
104 ERR_FAIL_COND(!camera);
105 camera->vaspect = p_enable;
106}
107
108bool RendererSceneCull::is_camera(RID p_camera) const {
109 return camera_owner.owns(p_camera);
110}
111
112/* OCCLUDER API */
113
114RID RendererSceneCull::occluder_allocate() {
115 return RendererSceneOcclusionCull::get_singleton()->occluder_allocate();
116}
117
118void RendererSceneCull::occluder_initialize(RID p_rid) {
119 RendererSceneOcclusionCull::get_singleton()->occluder_initialize(p_rid);
120}
121
122void RendererSceneCull::occluder_set_mesh(RID p_occluder, const PackedVector3Array &p_vertices, const PackedInt32Array &p_indices) {
123 RendererSceneOcclusionCull::get_singleton()->occluder_set_mesh(p_occluder, p_vertices, p_indices);
124}
125
126/* SCENARIO API */
127
128void RendererSceneCull::_instance_pair(Instance *p_A, Instance *p_B) {
129 RendererSceneCull *self = (RendererSceneCull *)singleton;
130 Instance *A = p_A;
131 Instance *B = p_B;
132
133 //instance indices are designed so greater always contains lesser
134 if (A->base_type > B->base_type) {
135 SWAP(A, B); //lesser always first
136 }
137
138 if (B->base_type == RS::INSTANCE_LIGHT && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) {
139 InstanceLightData *light = static_cast<InstanceLightData *>(B->base_data);
140 InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data);
141
142 geom->lights.insert(B);
143 light->geometries.insert(A);
144
145 if (geom->can_cast_shadows) {
146 light->shadow_dirty = true;
147 }
148
149 if (A->scenario && A->array_index >= 0) {
150 InstanceData &idata = A->scenario->instance_data[A->array_index];
151 idata.flags |= InstanceData::FLAG_GEOM_LIGHTING_DIRTY;
152 }
153
154 if (light->uses_projector) {
155 geom->projector_count++;
156 if (geom->projector_count == 1) {
157 InstanceData &idata = A->scenario->instance_data[A->array_index];
158 idata.flags |= InstanceData::FLAG_GEOM_PROJECTOR_SOFTSHADOW_DIRTY;
159 }
160 }
161
162 if (light->uses_softshadow) {
163 geom->softshadow_count++;
164 if (geom->softshadow_count == 1) {
165 InstanceData &idata = A->scenario->instance_data[A->array_index];
166 idata.flags |= InstanceData::FLAG_GEOM_PROJECTOR_SOFTSHADOW_DIRTY;
167 }
168 }
169
170 } else if (self->geometry_instance_pair_mask & (1 << RS::INSTANCE_REFLECTION_PROBE) && B->base_type == RS::INSTANCE_REFLECTION_PROBE && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) {
171 InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(B->base_data);
172 InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data);
173
174 geom->reflection_probes.insert(B);
175 reflection_probe->geometries.insert(A);
176
177 if (A->scenario && A->array_index >= 0) {
178 InstanceData &idata = A->scenario->instance_data[A->array_index];
179 idata.flags |= InstanceData::FLAG_GEOM_REFLECTION_DIRTY;
180 }
181
182 } else if (self->geometry_instance_pair_mask & (1 << RS::INSTANCE_DECAL) && B->base_type == RS::INSTANCE_DECAL && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) {
183 InstanceDecalData *decal = static_cast<InstanceDecalData *>(B->base_data);
184 InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data);
185
186 geom->decals.insert(B);
187 decal->geometries.insert(A);
188
189 if (A->scenario && A->array_index >= 0) {
190 InstanceData &idata = A->scenario->instance_data[A->array_index];
191 idata.flags |= InstanceData::FLAG_GEOM_DECAL_DIRTY;
192 }
193
194 } else if (B->base_type == RS::INSTANCE_LIGHTMAP && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) {
195 InstanceLightmapData *lightmap_data = static_cast<InstanceLightmapData *>(B->base_data);
196 InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data);
197
198 if (A->dynamic_gi) {
199 geom->lightmap_captures.insert(B);
200 lightmap_data->geometries.insert(A);
201
202 if (A->scenario && A->array_index >= 0) {
203 InstanceData &idata = A->scenario->instance_data[A->array_index];
204 idata.flags |= InstanceData::FLAG_LIGHTMAP_CAPTURE;
205 }
206 ((RendererSceneCull *)self)->_instance_queue_update(A, false, false); //need to update capture
207 }
208
209 } else if (self->geometry_instance_pair_mask & (1 << RS::INSTANCE_VOXEL_GI) && B->base_type == RS::INSTANCE_VOXEL_GI && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) {
210 InstanceVoxelGIData *voxel_gi = static_cast<InstanceVoxelGIData *>(B->base_data);
211 InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data);
212
213 geom->voxel_gi_instances.insert(B);
214
215 if (A->dynamic_gi) {
216 voxel_gi->dynamic_geometries.insert(A);
217 } else {
218 voxel_gi->geometries.insert(A);
219 }
220
221 if (A->scenario && A->array_index >= 0) {
222 InstanceData &idata = A->scenario->instance_data[A->array_index];
223 idata.flags |= InstanceData::FLAG_GEOM_VOXEL_GI_DIRTY;
224 }
225
226 } else if (B->base_type == RS::INSTANCE_VOXEL_GI && A->base_type == RS::INSTANCE_LIGHT) {
227 InstanceVoxelGIData *voxel_gi = static_cast<InstanceVoxelGIData *>(B->base_data);
228 voxel_gi->lights.insert(A);
229 } else if (B->base_type == RS::INSTANCE_PARTICLES_COLLISION && A->base_type == RS::INSTANCE_PARTICLES) {
230 InstanceParticlesCollisionData *collision = static_cast<InstanceParticlesCollisionData *>(B->base_data);
231 RSG::particles_storage->particles_add_collision(A->base, collision->instance);
232 }
233}
234
235void RendererSceneCull::_instance_unpair(Instance *p_A, Instance *p_B) {
236 RendererSceneCull *self = (RendererSceneCull *)singleton;
237 Instance *A = p_A;
238 Instance *B = p_B;
239
240 //instance indices are designed so greater always contains lesser
241 if (A->base_type > B->base_type) {
242 SWAP(A, B); //lesser always first
243 }
244
245 if (B->base_type == RS::INSTANCE_LIGHT && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) {
246 InstanceLightData *light = static_cast<InstanceLightData *>(B->base_data);
247 InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data);
248
249 geom->lights.erase(B);
250 light->geometries.erase(A);
251
252 if (geom->can_cast_shadows) {
253 light->shadow_dirty = true;
254 }
255
256 if (A->scenario && A->array_index >= 0) {
257 InstanceData &idata = A->scenario->instance_data[A->array_index];
258 idata.flags |= InstanceData::FLAG_GEOM_LIGHTING_DIRTY;
259 }
260
261 if (light->uses_projector) {
262#ifdef DEBUG_ENABLED
263 if (geom->projector_count == 0) {
264 ERR_PRINT("geom->projector_count==0 - BUG!");
265 }
266#endif
267 geom->projector_count--;
268 if (geom->projector_count == 0) {
269 InstanceData &idata = A->scenario->instance_data[A->array_index];
270 idata.flags |= InstanceData::FLAG_GEOM_PROJECTOR_SOFTSHADOW_DIRTY;
271 }
272 }
273
274 if (light->uses_softshadow) {
275#ifdef DEBUG_ENABLED
276 if (geom->softshadow_count == 0) {
277 ERR_PRINT("geom->softshadow_count==0 - BUG!");
278 }
279#endif
280 geom->softshadow_count--;
281 if (geom->softshadow_count == 0) {
282 InstanceData &idata = A->scenario->instance_data[A->array_index];
283 idata.flags |= InstanceData::FLAG_GEOM_PROJECTOR_SOFTSHADOW_DIRTY;
284 }
285 }
286
287 } else if (self->geometry_instance_pair_mask & (1 << RS::INSTANCE_REFLECTION_PROBE) && B->base_type == RS::INSTANCE_REFLECTION_PROBE && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) {
288 InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(B->base_data);
289 InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data);
290
291 geom->reflection_probes.erase(B);
292 reflection_probe->geometries.erase(A);
293
294 if (A->scenario && A->array_index >= 0) {
295 InstanceData &idata = A->scenario->instance_data[A->array_index];
296 idata.flags |= InstanceData::FLAG_GEOM_REFLECTION_DIRTY;
297 }
298
299 } else if (self->geometry_instance_pair_mask & (1 << RS::INSTANCE_DECAL) && B->base_type == RS::INSTANCE_DECAL && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) {
300 InstanceDecalData *decal = static_cast<InstanceDecalData *>(B->base_data);
301 InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data);
302
303 geom->decals.erase(B);
304 decal->geometries.erase(A);
305
306 if (A->scenario && A->array_index >= 0) {
307 InstanceData &idata = A->scenario->instance_data[A->array_index];
308 idata.flags |= InstanceData::FLAG_GEOM_DECAL_DIRTY;
309 }
310
311 } else if (B->base_type == RS::INSTANCE_LIGHTMAP && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) {
312 InstanceLightmapData *lightmap_data = static_cast<InstanceLightmapData *>(B->base_data);
313 InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data);
314 if (A->dynamic_gi) {
315 geom->lightmap_captures.erase(B);
316
317 if (geom->lightmap_captures.is_empty() && A->scenario && A->array_index >= 0) {
318 InstanceData &idata = A->scenario->instance_data[A->array_index];
319 idata.flags &= ~uint32_t(InstanceData::FLAG_LIGHTMAP_CAPTURE);
320 }
321
322 lightmap_data->geometries.erase(A);
323 ((RendererSceneCull *)self)->_instance_queue_update(A, false, false); //need to update capture
324 }
325
326 } else if (self->geometry_instance_pair_mask & (1 << RS::INSTANCE_VOXEL_GI) && B->base_type == RS::INSTANCE_VOXEL_GI && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) {
327 InstanceVoxelGIData *voxel_gi = static_cast<InstanceVoxelGIData *>(B->base_data);
328 InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data);
329
330 geom->voxel_gi_instances.erase(B);
331 if (A->dynamic_gi) {
332 voxel_gi->dynamic_geometries.erase(A);
333 } else {
334 voxel_gi->geometries.erase(A);
335 }
336
337 if (A->scenario && A->array_index >= 0) {
338 InstanceData &idata = A->scenario->instance_data[A->array_index];
339 idata.flags |= InstanceData::FLAG_GEOM_VOXEL_GI_DIRTY;
340 }
341
342 } else if (B->base_type == RS::INSTANCE_VOXEL_GI && A->base_type == RS::INSTANCE_LIGHT) {
343 InstanceVoxelGIData *voxel_gi = static_cast<InstanceVoxelGIData *>(B->base_data);
344 voxel_gi->lights.erase(A);
345 } else if (B->base_type == RS::INSTANCE_PARTICLES_COLLISION && A->base_type == RS::INSTANCE_PARTICLES) {
346 InstanceParticlesCollisionData *collision = static_cast<InstanceParticlesCollisionData *>(B->base_data);
347 RSG::particles_storage->particles_remove_collision(A->base, collision->instance);
348 }
349}
350
351RID RendererSceneCull::scenario_allocate() {
352 return scenario_owner.allocate_rid();
353}
354void RendererSceneCull::scenario_initialize(RID p_rid) {
355 scenario_owner.initialize_rid(p_rid);
356
357 Scenario *scenario = scenario_owner.get_or_null(p_rid);
358 scenario->self = p_rid;
359
360 scenario->reflection_probe_shadow_atlas = RSG::light_storage->shadow_atlas_create();
361 RSG::light_storage->shadow_atlas_set_size(scenario->reflection_probe_shadow_atlas, 1024); //make enough shadows for close distance, don't bother with rest
362 RSG::light_storage->shadow_atlas_set_quadrant_subdivision(scenario->reflection_probe_shadow_atlas, 0, 4);
363 RSG::light_storage->shadow_atlas_set_quadrant_subdivision(scenario->reflection_probe_shadow_atlas, 1, 4);
364 RSG::light_storage->shadow_atlas_set_quadrant_subdivision(scenario->reflection_probe_shadow_atlas, 2, 4);
365 RSG::light_storage->shadow_atlas_set_quadrant_subdivision(scenario->reflection_probe_shadow_atlas, 3, 8);
366
367 scenario->reflection_atlas = RSG::light_storage->reflection_atlas_create();
368
369 scenario->instance_aabbs.set_page_pool(&instance_aabb_page_pool);
370 scenario->instance_data.set_page_pool(&instance_data_page_pool);
371 scenario->instance_visibility.set_page_pool(&instance_visibility_data_page_pool);
372
373 RendererSceneOcclusionCull::get_singleton()->add_scenario(p_rid);
374}
375
376void RendererSceneCull::scenario_set_environment(RID p_scenario, RID p_environment) {
377 Scenario *scenario = scenario_owner.get_or_null(p_scenario);
378 ERR_FAIL_COND(!scenario);
379 scenario->environment = p_environment;
380}
381
382void RendererSceneCull::scenario_set_camera_attributes(RID p_scenario, RID p_camera_attributes) {
383 Scenario *scenario = scenario_owner.get_or_null(p_scenario);
384 ERR_FAIL_COND(!scenario);
385 scenario->camera_attributes = p_camera_attributes;
386}
387
388void RendererSceneCull::scenario_set_fallback_environment(RID p_scenario, RID p_environment) {
389 Scenario *scenario = scenario_owner.get_or_null(p_scenario);
390 ERR_FAIL_COND(!scenario);
391 scenario->fallback_environment = p_environment;
392}
393
394void RendererSceneCull::scenario_set_reflection_atlas_size(RID p_scenario, int p_reflection_size, int p_reflection_count) {
395 Scenario *scenario = scenario_owner.get_or_null(p_scenario);
396 ERR_FAIL_COND(!scenario);
397 RSG::light_storage->reflection_atlas_set_size(scenario->reflection_atlas, p_reflection_size, p_reflection_count);
398}
399
400bool RendererSceneCull::is_scenario(RID p_scenario) const {
401 return scenario_owner.owns(p_scenario);
402}
403
404RID RendererSceneCull::scenario_get_environment(RID p_scenario) {
405 Scenario *scenario = scenario_owner.get_or_null(p_scenario);
406 ERR_FAIL_COND_V(!scenario, RID());
407 return scenario->environment;
408}
409
410void RendererSceneCull::scenario_remove_viewport_visibility_mask(RID p_scenario, RID p_viewport) {
411 Scenario *scenario = scenario_owner.get_or_null(p_scenario);
412 ERR_FAIL_COND(!scenario);
413 if (!scenario->viewport_visibility_masks.has(p_viewport)) {
414 return;
415 }
416
417 uint64_t mask = scenario->viewport_visibility_masks[p_viewport];
418 scenario->used_viewport_visibility_bits &= ~mask;
419 scenario->viewport_visibility_masks.erase(p_viewport);
420}
421
422void RendererSceneCull::scenario_add_viewport_visibility_mask(RID p_scenario, RID p_viewport) {
423 Scenario *scenario = scenario_owner.get_or_null(p_scenario);
424 ERR_FAIL_COND(!scenario);
425 ERR_FAIL_COND(scenario->viewport_visibility_masks.has(p_viewport));
426
427 uint64_t new_mask = 1;
428 while (new_mask & scenario->used_viewport_visibility_bits) {
429 new_mask <<= 1;
430 }
431
432 if (new_mask == 0) {
433 ERR_PRINT("Only 64 viewports per scenario allowed when using visibility ranges.");
434 new_mask = ((uint64_t)1) << 63;
435 }
436
437 scenario->viewport_visibility_masks[p_viewport] = new_mask;
438 scenario->used_viewport_visibility_bits |= new_mask;
439}
440
441/* INSTANCING API */
442
443void RendererSceneCull::_instance_queue_update(Instance *p_instance, bool p_update_aabb, bool p_update_dependencies) {
444 if (p_update_aabb) {
445 p_instance->update_aabb = true;
446 }
447 if (p_update_dependencies) {
448 p_instance->update_dependencies = true;
449 }
450
451 if (p_instance->update_item.in_list()) {
452 return;
453 }
454
455 _instance_update_list.add(&p_instance->update_item);
456}
457
458RID RendererSceneCull::instance_allocate() {
459 return instance_owner.allocate_rid();
460}
461void RendererSceneCull::instance_initialize(RID p_rid) {
462 instance_owner.initialize_rid(p_rid);
463 Instance *instance = instance_owner.get_or_null(p_rid);
464 instance->self = p_rid;
465}
466
467void RendererSceneCull::_instance_update_mesh_instance(Instance *p_instance) {
468 bool needs_instance = RSG::mesh_storage->mesh_needs_instance(p_instance->base, p_instance->skeleton.is_valid());
469 if (needs_instance != p_instance->mesh_instance.is_valid()) {
470 if (needs_instance) {
471 p_instance->mesh_instance = RSG::mesh_storage->mesh_instance_create(p_instance->base);
472
473 } else {
474 RSG::mesh_storage->mesh_instance_free(p_instance->mesh_instance);
475 p_instance->mesh_instance = RID();
476 }
477
478 InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(p_instance->base_data);
479 geom->geometry_instance->set_mesh_instance(p_instance->mesh_instance);
480
481 if (p_instance->scenario && p_instance->array_index >= 0) {
482 InstanceData &idata = p_instance->scenario->instance_data[p_instance->array_index];
483 if (p_instance->mesh_instance.is_valid()) {
484 idata.flags |= InstanceData::FLAG_USES_MESH_INSTANCE;
485 } else {
486 idata.flags &= ~uint32_t(InstanceData::FLAG_USES_MESH_INSTANCE);
487 }
488 }
489 }
490
491 if (p_instance->mesh_instance.is_valid()) {
492 RSG::mesh_storage->mesh_instance_set_skeleton(p_instance->mesh_instance, p_instance->skeleton);
493 }
494}
495
496void RendererSceneCull::instance_set_base(RID p_instance, RID p_base) {
497 Instance *instance = instance_owner.get_or_null(p_instance);
498 ERR_FAIL_COND(!instance);
499
500 Scenario *scenario = instance->scenario;
501
502 if (instance->base_type != RS::INSTANCE_NONE) {
503 //free anything related to that base
504
505 if (scenario && instance->indexer_id.is_valid()) {
506 _unpair_instance(instance);
507 }
508
509 if (instance->mesh_instance.is_valid()) {
510 RSG::mesh_storage->mesh_instance_free(instance->mesh_instance);
511 instance->mesh_instance = RID();
512 // no need to set instance data flag here, as it was freed above
513 }
514
515 switch (instance->base_type) {
516 case RS::INSTANCE_MESH:
517 case RS::INSTANCE_MULTIMESH:
518 case RS::INSTANCE_PARTICLES: {
519 InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data);
520 scene_render->geometry_instance_free(geom->geometry_instance);
521 } break;
522 case RS::INSTANCE_LIGHT: {
523 InstanceLightData *light = static_cast<InstanceLightData *>(instance->base_data);
524
525 if (scenario && instance->visible && RSG::light_storage->light_get_type(instance->base) != RS::LIGHT_DIRECTIONAL && light->bake_mode == RS::LIGHT_BAKE_DYNAMIC) {
526 scenario->dynamic_lights.erase(light->instance);
527 }
528
529#ifdef DEBUG_ENABLED
530 if (light->geometries.size()) {
531 ERR_PRINT("BUG, indexing did not unpair geometries from light.");
532 }
533#endif
534 if (scenario && light->D) {
535 scenario->directional_lights.erase(light->D);
536 light->D = nullptr;
537 }
538 RSG::light_storage->light_instance_free(light->instance);
539 } break;
540 case RS::INSTANCE_PARTICLES_COLLISION: {
541 InstanceParticlesCollisionData *collision = static_cast<InstanceParticlesCollisionData *>(instance->base_data);
542 RSG::utilities->free(collision->instance);
543 } break;
544 case RS::INSTANCE_FOG_VOLUME: {
545 InstanceFogVolumeData *volume = static_cast<InstanceFogVolumeData *>(instance->base_data);
546 scene_render->free(volume->instance);
547 } break;
548 case RS::INSTANCE_VISIBLITY_NOTIFIER: {
549 //none
550 } break;
551 case RS::INSTANCE_REFLECTION_PROBE: {
552 InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(instance->base_data);
553 RSG::light_storage->reflection_probe_instance_free(reflection_probe->instance);
554 if (reflection_probe->update_list.in_list()) {
555 reflection_probe_render_list.remove(&reflection_probe->update_list);
556 }
557 } break;
558 case RS::INSTANCE_DECAL: {
559 InstanceDecalData *decal = static_cast<InstanceDecalData *>(instance->base_data);
560 RSG::texture_storage->decal_instance_free(decal->instance);
561
562 } break;
563 case RS::INSTANCE_LIGHTMAP: {
564 InstanceLightmapData *lightmap_data = static_cast<InstanceLightmapData *>(instance->base_data);
565 //erase dependencies, since no longer a lightmap
566 while (lightmap_data->users.begin()) {
567 instance_geometry_set_lightmap((*lightmap_data->users.begin())->self, RID(), Rect2(), 0);
568 }
569 RSG::light_storage->lightmap_instance_free(lightmap_data->instance);
570 } break;
571 case RS::INSTANCE_VOXEL_GI: {
572 InstanceVoxelGIData *voxel_gi = static_cast<InstanceVoxelGIData *>(instance->base_data);
573#ifdef DEBUG_ENABLED
574 if (voxel_gi->geometries.size()) {
575 ERR_PRINT("BUG, indexing did not unpair geometries from VoxelGI.");
576 }
577#endif
578#ifdef DEBUG_ENABLED
579 if (voxel_gi->lights.size()) {
580 ERR_PRINT("BUG, indexing did not unpair lights from VoxelGI.");
581 }
582#endif
583 if (voxel_gi->update_element.in_list()) {
584 voxel_gi_update_list.remove(&voxel_gi->update_element);
585 }
586
587 scene_render->free(voxel_gi->probe_instance);
588
589 } break;
590 case RS::INSTANCE_OCCLUDER: {
591 if (scenario && instance->visible) {
592 RendererSceneOcclusionCull::get_singleton()->scenario_remove_instance(instance->scenario->self, p_instance);
593 }
594 } break;
595 default: {
596 }
597 }
598
599 if (instance->base_data) {
600 memdelete(instance->base_data);
601 instance->base_data = nullptr;
602 }
603
604 instance->materials.clear();
605 }
606
607 instance->base_type = RS::INSTANCE_NONE;
608 instance->base = RID();
609
610 if (p_base.is_valid()) {
611 instance->base_type = RSG::utilities->get_base_type(p_base);
612
613 // fix up a specific malfunctioning case before the switch, so it can be handled
614 if (instance->base_type == RS::INSTANCE_NONE && RendererSceneOcclusionCull::get_singleton()->is_occluder(p_base)) {
615 instance->base_type = RS::INSTANCE_OCCLUDER;
616 }
617
618 switch (instance->base_type) {
619 case RS::INSTANCE_NONE: {
620 ERR_PRINT_ONCE("unimplemented base type encountered in renderer scene cull");
621 return;
622 }
623 case RS::INSTANCE_LIGHT: {
624 InstanceLightData *light = memnew(InstanceLightData);
625
626 if (scenario && RSG::light_storage->light_get_type(p_base) == RS::LIGHT_DIRECTIONAL) {
627 light->D = scenario->directional_lights.push_back(instance);
628 }
629
630 light->instance = RSG::light_storage->light_instance_create(p_base);
631
632 instance->base_data = light;
633 } break;
634 case RS::INSTANCE_MESH:
635 case RS::INSTANCE_MULTIMESH:
636 case RS::INSTANCE_PARTICLES: {
637 InstanceGeometryData *geom = memnew(InstanceGeometryData);
638 instance->base_data = geom;
639 geom->geometry_instance = scene_render->geometry_instance_create(p_base);
640
641 ERR_FAIL_NULL(geom->geometry_instance);
642
643 geom->geometry_instance->set_skeleton(instance->skeleton);
644 geom->geometry_instance->set_material_override(instance->material_override);
645 geom->geometry_instance->set_material_overlay(instance->material_overlay);
646 geom->geometry_instance->set_surface_materials(instance->materials);
647 geom->geometry_instance->set_transform(instance->transform, instance->aabb, instance->transformed_aabb);
648 geom->geometry_instance->set_layer_mask(instance->layer_mask);
649 geom->geometry_instance->set_pivot_data(instance->sorting_offset, instance->use_aabb_center);
650 geom->geometry_instance->set_lod_bias(instance->lod_bias);
651 geom->geometry_instance->set_transparency(instance->transparency);
652 geom->geometry_instance->set_use_baked_light(instance->baked_light);
653 geom->geometry_instance->set_use_dynamic_gi(instance->dynamic_gi);
654 geom->geometry_instance->set_use_lightmap(RID(), instance->lightmap_uv_scale, instance->lightmap_slice_index);
655 geom->geometry_instance->set_instance_shader_uniforms_offset(instance->instance_allocated_shader_uniforms_offset);
656 geom->geometry_instance->set_cast_double_sided_shadows(instance->cast_shadows == RS::SHADOW_CASTING_SETTING_DOUBLE_SIDED);
657 if (instance->lightmap_sh.size() == 9) {
658 geom->geometry_instance->set_lightmap_capture(instance->lightmap_sh.ptr());
659 }
660
661 for (Instance *E : instance->visibility_dependencies) {
662 Instance *dep_instance = E;
663 ERR_CONTINUE(dep_instance->array_index == -1);
664 ERR_CONTINUE(dep_instance->scenario->instance_data[dep_instance->array_index].parent_array_index != -1);
665 dep_instance->scenario->instance_data[dep_instance->array_index].parent_array_index = instance->array_index;
666 }
667 } break;
668 case RS::INSTANCE_PARTICLES_COLLISION: {
669 InstanceParticlesCollisionData *collision = memnew(InstanceParticlesCollisionData);
670 collision->instance = RSG::particles_storage->particles_collision_instance_create(p_base);
671 RSG::particles_storage->particles_collision_instance_set_active(collision->instance, instance->visible);
672 instance->base_data = collision;
673 } break;
674 case RS::INSTANCE_FOG_VOLUME: {
675 InstanceFogVolumeData *volume = memnew(InstanceFogVolumeData);
676 volume->instance = scene_render->fog_volume_instance_create(p_base);
677 scene_render->fog_volume_instance_set_active(volume->instance, instance->visible);
678 instance->base_data = volume;
679 } break;
680 case RS::INSTANCE_VISIBLITY_NOTIFIER: {
681 InstanceVisibilityNotifierData *vnd = memnew(InstanceVisibilityNotifierData);
682 vnd->base = p_base;
683 instance->base_data = vnd;
684 } break;
685 case RS::INSTANCE_REFLECTION_PROBE: {
686 InstanceReflectionProbeData *reflection_probe = memnew(InstanceReflectionProbeData);
687 reflection_probe->owner = instance;
688 instance->base_data = reflection_probe;
689
690 reflection_probe->instance = RSG::light_storage->reflection_probe_instance_create(p_base);
691 } break;
692 case RS::INSTANCE_DECAL: {
693 InstanceDecalData *decal = memnew(InstanceDecalData);
694 decal->owner = instance;
695 instance->base_data = decal;
696
697 decal->instance = RSG::texture_storage->decal_instance_create(p_base);
698 RSG::texture_storage->decal_instance_set_sorting_offset(decal->instance, instance->sorting_offset);
699 } break;
700 case RS::INSTANCE_LIGHTMAP: {
701 InstanceLightmapData *lightmap_data = memnew(InstanceLightmapData);
702 instance->base_data = lightmap_data;
703 lightmap_data->instance = RSG::light_storage->lightmap_instance_create(p_base);
704 } break;
705 case RS::INSTANCE_VOXEL_GI: {
706 InstanceVoxelGIData *voxel_gi = memnew(InstanceVoxelGIData);
707 instance->base_data = voxel_gi;
708 voxel_gi->owner = instance;
709
710 if (scenario && !voxel_gi->update_element.in_list()) {
711 voxel_gi_update_list.add(&voxel_gi->update_element);
712 }
713
714 voxel_gi->probe_instance = scene_render->voxel_gi_instance_create(p_base);
715
716 } break;
717 case RS::INSTANCE_OCCLUDER: {
718 if (scenario) {
719 RendererSceneOcclusionCull::get_singleton()->scenario_set_instance(scenario->self, p_instance, p_base, instance->transform, instance->visible);
720 }
721 } break;
722 default: {
723 }
724 }
725
726 instance->base = p_base;
727
728 if (instance->base_type == RS::INSTANCE_MESH) {
729 _instance_update_mesh_instance(instance);
730 }
731
732 //forcefully update the dependency now, so if for some reason it gets removed, we can immediately clear it
733 RSG::utilities->base_update_dependency(p_base, &instance->dependency_tracker);
734 }
735
736 _instance_queue_update(instance, true, true);
737}
738
739void RendererSceneCull::instance_set_scenario(RID p_instance, RID p_scenario) {
740 Instance *instance = instance_owner.get_or_null(p_instance);
741 ERR_FAIL_COND(!instance);
742
743 if (instance->scenario) {
744 instance->scenario->instances.remove(&instance->scenario_item);
745
746 if (instance->indexer_id.is_valid()) {
747 _unpair_instance(instance);
748 }
749
750 switch (instance->base_type) {
751 case RS::INSTANCE_LIGHT: {
752 InstanceLightData *light = static_cast<InstanceLightData *>(instance->base_data);
753 if (instance->visible && RSG::light_storage->light_get_type(instance->base) != RS::LIGHT_DIRECTIONAL && light->bake_mode == RS::LIGHT_BAKE_DYNAMIC) {
754 instance->scenario->dynamic_lights.erase(light->instance);
755 }
756
757#ifdef DEBUG_ENABLED
758 if (light->geometries.size()) {
759 ERR_PRINT("BUG, indexing did not unpair geometries from light.");
760 }
761#endif
762 if (light->D) {
763 instance->scenario->directional_lights.erase(light->D);
764 light->D = nullptr;
765 }
766 } break;
767 case RS::INSTANCE_REFLECTION_PROBE: {
768 InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(instance->base_data);
769 RSG::light_storage->reflection_probe_release_atlas_index(reflection_probe->instance);
770
771 } break;
772 case RS::INSTANCE_PARTICLES_COLLISION: {
773 heightfield_particle_colliders_update_list.erase(instance);
774 } break;
775 case RS::INSTANCE_VOXEL_GI: {
776 InstanceVoxelGIData *voxel_gi = static_cast<InstanceVoxelGIData *>(instance->base_data);
777
778#ifdef DEBUG_ENABLED
779 if (voxel_gi->geometries.size()) {
780 ERR_PRINT("BUG, indexing did not unpair geometries from VoxelGI.");
781 }
782#endif
783#ifdef DEBUG_ENABLED
784 if (voxel_gi->lights.size()) {
785 ERR_PRINT("BUG, indexing did not unpair lights from VoxelGI.");
786 }
787#endif
788
789 if (voxel_gi->update_element.in_list()) {
790 voxel_gi_update_list.remove(&voxel_gi->update_element);
791 }
792 } break;
793 case RS::INSTANCE_OCCLUDER: {
794 if (instance->visible) {
795 RendererSceneOcclusionCull::get_singleton()->scenario_remove_instance(instance->scenario->self, p_instance);
796 }
797 } break;
798 default: {
799 }
800 }
801
802 instance->scenario = nullptr;
803 }
804
805 if (p_scenario.is_valid()) {
806 Scenario *scenario = scenario_owner.get_or_null(p_scenario);
807 ERR_FAIL_COND(!scenario);
808
809 instance->scenario = scenario;
810
811 scenario->instances.add(&instance->scenario_item);
812
813 switch (instance->base_type) {
814 case RS::INSTANCE_LIGHT: {
815 InstanceLightData *light = static_cast<InstanceLightData *>(instance->base_data);
816
817 if (RSG::light_storage->light_get_type(instance->base) == RS::LIGHT_DIRECTIONAL) {
818 light->D = scenario->directional_lights.push_back(instance);
819 }
820 } break;
821 case RS::INSTANCE_VOXEL_GI: {
822 InstanceVoxelGIData *voxel_gi = static_cast<InstanceVoxelGIData *>(instance->base_data);
823 if (!voxel_gi->update_element.in_list()) {
824 voxel_gi_update_list.add(&voxel_gi->update_element);
825 }
826 } break;
827 case RS::INSTANCE_OCCLUDER: {
828 RendererSceneOcclusionCull::get_singleton()->scenario_set_instance(scenario->self, p_instance, instance->base, instance->transform, instance->visible);
829 } break;
830 default: {
831 }
832 }
833
834 _instance_queue_update(instance, true, true);
835 }
836}
837
838void RendererSceneCull::instance_set_layer_mask(RID p_instance, uint32_t p_mask) {
839 Instance *instance = instance_owner.get_or_null(p_instance);
840 ERR_FAIL_COND(!instance);
841
842 if (instance->layer_mask == p_mask) {
843 return;
844 }
845
846 instance->layer_mask = p_mask;
847 if (instance->scenario && instance->array_index >= 0) {
848 instance->scenario->instance_data[instance->array_index].layer_mask = p_mask;
849 }
850
851 if ((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK && instance->base_data) {
852 InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data);
853 ERR_FAIL_NULL(geom->geometry_instance);
854 geom->geometry_instance->set_layer_mask(p_mask);
855
856 if (geom->can_cast_shadows) {
857 for (HashSet<RendererSceneCull::Instance *>::Iterator I = geom->lights.begin(); I != geom->lights.end(); ++I) {
858 InstanceLightData *light = static_cast<InstanceLightData *>((*I)->base_data);
859 light->shadow_dirty = true;
860 }
861 }
862 }
863}
864
865void RendererSceneCull::instance_set_pivot_data(RID p_instance, float p_sorting_offset, bool p_use_aabb_center) {
866 Instance *instance = instance_owner.get_or_null(p_instance);
867 ERR_FAIL_COND(!instance);
868
869 instance->sorting_offset = p_sorting_offset;
870 instance->use_aabb_center = p_use_aabb_center;
871
872 if ((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK && instance->base_data) {
873 InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data);
874 ERR_FAIL_NULL(geom->geometry_instance);
875 geom->geometry_instance->set_pivot_data(p_sorting_offset, p_use_aabb_center);
876 } else if (instance->base_type == RS::INSTANCE_DECAL && instance->base_data) {
877 InstanceDecalData *decal = static_cast<InstanceDecalData *>(instance->base_data);
878 RSG::texture_storage->decal_instance_set_sorting_offset(decal->instance, instance->sorting_offset);
879 }
880}
881
882void RendererSceneCull::instance_geometry_set_transparency(RID p_instance, float p_transparency) {
883 Instance *instance = instance_owner.get_or_null(p_instance);
884 ERR_FAIL_COND(!instance);
885
886 instance->transparency = p_transparency;
887
888 if ((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK && instance->base_data) {
889 InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data);
890 ERR_FAIL_NULL(geom->geometry_instance);
891 geom->geometry_instance->set_transparency(p_transparency);
892 }
893}
894
895void RendererSceneCull::instance_set_transform(RID p_instance, const Transform3D &p_transform) {
896 Instance *instance = instance_owner.get_or_null(p_instance);
897 ERR_FAIL_COND(!instance);
898
899 if (instance->transform == p_transform) {
900 return; //must be checked to avoid worst evil
901 }
902
903#ifdef DEBUG_ENABLED
904
905 for (int i = 0; i < 4; i++) {
906 const Vector3 &v = i < 3 ? p_transform.basis.rows[i] : p_transform.origin;
907 ERR_FAIL_COND(!v.is_finite());
908 }
909
910#endif
911 instance->transform = p_transform;
912 _instance_queue_update(instance, true);
913}
914
915void RendererSceneCull::instance_attach_object_instance_id(RID p_instance, ObjectID p_id) {
916 Instance *instance = instance_owner.get_or_null(p_instance);
917 ERR_FAIL_COND(!instance);
918
919 instance->object_id = p_id;
920}
921
922void RendererSceneCull::instance_set_blend_shape_weight(RID p_instance, int p_shape, float p_weight) {
923 Instance *instance = instance_owner.get_or_null(p_instance);
924 ERR_FAIL_COND(!instance);
925
926 if (instance->update_item.in_list()) {
927 _update_dirty_instance(instance);
928 }
929
930 if (instance->mesh_instance.is_valid()) {
931 RSG::mesh_storage->mesh_instance_set_blend_shape_weight(instance->mesh_instance, p_shape, p_weight);
932 }
933}
934
935void RendererSceneCull::instance_set_surface_override_material(RID p_instance, int p_surface, RID p_material) {
936 Instance *instance = instance_owner.get_or_null(p_instance);
937 ERR_FAIL_COND(!instance);
938
939 if (instance->base_type == RS::INSTANCE_MESH) {
940 //may not have been updated yet, may also have not been set yet. When updated will be correcte, worst case
941 instance->materials.resize(MAX(p_surface + 1, RSG::mesh_storage->mesh_get_surface_count(instance->base)));
942 }
943
944 ERR_FAIL_INDEX(p_surface, instance->materials.size());
945
946 instance->materials.write[p_surface] = p_material;
947
948 _instance_queue_update(instance, false, true);
949}
950
951void RendererSceneCull::instance_set_visible(RID p_instance, bool p_visible) {
952 Instance *instance = instance_owner.get_or_null(p_instance);
953 ERR_FAIL_COND(!instance);
954
955 if (instance->visible == p_visible) {
956 return;
957 }
958
959 instance->visible = p_visible;
960
961 if (p_visible) {
962 if (instance->scenario != nullptr) {
963 _instance_queue_update(instance, true, false);
964 }
965 } else if (instance->indexer_id.is_valid()) {
966 _unpair_instance(instance);
967 }
968
969 if (instance->base_type == RS::INSTANCE_LIGHT) {
970 InstanceLightData *light = static_cast<InstanceLightData *>(instance->base_data);
971 if (instance->scenario && RSG::light_storage->light_get_type(instance->base) != RS::LIGHT_DIRECTIONAL && light->bake_mode == RS::LIGHT_BAKE_DYNAMIC) {
972 if (p_visible) {
973 instance->scenario->dynamic_lights.push_back(light->instance);
974 } else {
975 instance->scenario->dynamic_lights.erase(light->instance);
976 }
977 }
978 }
979
980 if (instance->base_type == RS::INSTANCE_PARTICLES_COLLISION) {
981 InstanceParticlesCollisionData *collision = static_cast<InstanceParticlesCollisionData *>(instance->base_data);
982 RSG::particles_storage->particles_collision_instance_set_active(collision->instance, p_visible);
983 }
984
985 if (instance->base_type == RS::INSTANCE_FOG_VOLUME) {
986 InstanceFogVolumeData *volume = static_cast<InstanceFogVolumeData *>(instance->base_data);
987 scene_render->fog_volume_instance_set_active(volume->instance, p_visible);
988 }
989
990 if (instance->base_type == RS::INSTANCE_OCCLUDER) {
991 if (instance->scenario) {
992 RendererSceneOcclusionCull::get_singleton()->scenario_set_instance(instance->scenario->self, p_instance, instance->base, instance->transform, p_visible);
993 }
994 }
995}
996
997inline bool is_geometry_instance(RenderingServer::InstanceType p_type) {
998 return p_type == RS::INSTANCE_MESH || p_type == RS::INSTANCE_MULTIMESH || p_type == RS::INSTANCE_PARTICLES;
999}
1000
1001void RendererSceneCull::instance_set_custom_aabb(RID p_instance, AABB p_aabb) {
1002 Instance *instance = instance_owner.get_or_null(p_instance);
1003 ERR_FAIL_COND(!instance);
1004 ERR_FAIL_COND(!is_geometry_instance(instance->base_type));
1005
1006 if (p_aabb != AABB()) {
1007 // Set custom AABB
1008 if (instance->custom_aabb == nullptr) {
1009 instance->custom_aabb = memnew(AABB);
1010 }
1011 *instance->custom_aabb = p_aabb;
1012
1013 } else {
1014 // Clear custom AABB
1015 if (instance->custom_aabb != nullptr) {
1016 memdelete(instance->custom_aabb);
1017 instance->custom_aabb = nullptr;
1018 }
1019 }
1020
1021 if (instance->scenario) {
1022 _instance_queue_update(instance, true, false);
1023 }
1024}
1025
1026void RendererSceneCull::instance_attach_skeleton(RID p_instance, RID p_skeleton) {
1027 Instance *instance = instance_owner.get_or_null(p_instance);
1028 ERR_FAIL_COND(!instance);
1029
1030 if (instance->skeleton == p_skeleton) {
1031 return;
1032 }
1033
1034 instance->skeleton = p_skeleton;
1035
1036 if (p_skeleton.is_valid()) {
1037 //update the dependency now, so if cleared, we remove it
1038 RSG::mesh_storage->skeleton_update_dependency(p_skeleton, &instance->dependency_tracker);
1039 }
1040
1041 _instance_queue_update(instance, true, true);
1042
1043 if ((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK && instance->base_data) {
1044 _instance_update_mesh_instance(instance);
1045
1046 InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data);
1047 ERR_FAIL_NULL(geom->geometry_instance);
1048 geom->geometry_instance->set_skeleton(p_skeleton);
1049 }
1050}
1051
1052void RendererSceneCull::instance_set_extra_visibility_margin(RID p_instance, real_t p_margin) {
1053 Instance *instance = instance_owner.get_or_null(p_instance);
1054 ERR_FAIL_COND(!instance);
1055
1056 instance->extra_margin = p_margin;
1057 _instance_queue_update(instance, true, false);
1058}
1059
1060void RendererSceneCull::instance_set_ignore_culling(RID p_instance, bool p_enabled) {
1061 Instance *instance = instance_owner.get_or_null(p_instance);
1062 ERR_FAIL_COND(!instance);
1063 instance->ignore_all_culling = p_enabled;
1064
1065 if (instance->scenario && instance->array_index >= 0) {
1066 InstanceData &idata = instance->scenario->instance_data[instance->array_index];
1067 if (instance->ignore_all_culling) {
1068 idata.flags |= InstanceData::FLAG_IGNORE_ALL_CULLING;
1069 } else {
1070 idata.flags &= ~uint32_t(InstanceData::FLAG_IGNORE_ALL_CULLING);
1071 }
1072 }
1073}
1074
1075Vector<ObjectID> RendererSceneCull::instances_cull_aabb(const AABB &p_aabb, RID p_scenario) const {
1076 Vector<ObjectID> instances;
1077 Scenario *scenario = scenario_owner.get_or_null(p_scenario);
1078 ERR_FAIL_COND_V(!scenario, instances);
1079
1080 const_cast<RendererSceneCull *>(this)->update_dirty_instances(); // check dirty instances before culling
1081
1082 struct CullAABB {
1083 Vector<ObjectID> instances;
1084 _FORCE_INLINE_ bool operator()(void *p_data) {
1085 Instance *p_instance = (Instance *)p_data;
1086 if (!p_instance->object_id.is_null()) {
1087 instances.push_back(p_instance->object_id);
1088 }
1089 return false;
1090 }
1091 };
1092
1093 CullAABB cull_aabb;
1094 scenario->indexers[Scenario::INDEXER_GEOMETRY].aabb_query(p_aabb, cull_aabb);
1095 scenario->indexers[Scenario::INDEXER_VOLUMES].aabb_query(p_aabb, cull_aabb);
1096 return cull_aabb.instances;
1097}
1098
1099Vector<ObjectID> RendererSceneCull::instances_cull_ray(const Vector3 &p_from, const Vector3 &p_to, RID p_scenario) const {
1100 Vector<ObjectID> instances;
1101 Scenario *scenario = scenario_owner.get_or_null(p_scenario);
1102 ERR_FAIL_COND_V(!scenario, instances);
1103 const_cast<RendererSceneCull *>(this)->update_dirty_instances(); // check dirty instances before culling
1104
1105 struct CullRay {
1106 Vector<ObjectID> instances;
1107 _FORCE_INLINE_ bool operator()(void *p_data) {
1108 Instance *p_instance = (Instance *)p_data;
1109 if (!p_instance->object_id.is_null()) {
1110 instances.push_back(p_instance->object_id);
1111 }
1112 return false;
1113 }
1114 };
1115
1116 CullRay cull_ray;
1117 scenario->indexers[Scenario::INDEXER_GEOMETRY].ray_query(p_from, p_to, cull_ray);
1118 scenario->indexers[Scenario::INDEXER_VOLUMES].ray_query(p_from, p_to, cull_ray);
1119 return cull_ray.instances;
1120}
1121
1122Vector<ObjectID> RendererSceneCull::instances_cull_convex(const Vector<Plane> &p_convex, RID p_scenario) const {
1123 Vector<ObjectID> instances;
1124 Scenario *scenario = scenario_owner.get_or_null(p_scenario);
1125 ERR_FAIL_COND_V(!scenario, instances);
1126 const_cast<RendererSceneCull *>(this)->update_dirty_instances(); // check dirty instances before culling
1127
1128 Vector<Vector3> points = Geometry3D::compute_convex_mesh_points(&p_convex[0], p_convex.size());
1129
1130 struct CullConvex {
1131 Vector<ObjectID> instances;
1132 _FORCE_INLINE_ bool operator()(void *p_data) {
1133 Instance *p_instance = (Instance *)p_data;
1134 if (!p_instance->object_id.is_null()) {
1135 instances.push_back(p_instance->object_id);
1136 }
1137 return false;
1138 }
1139 };
1140
1141 CullConvex cull_convex;
1142 scenario->indexers[Scenario::INDEXER_GEOMETRY].convex_query(p_convex.ptr(), p_convex.size(), points.ptr(), points.size(), cull_convex);
1143 scenario->indexers[Scenario::INDEXER_VOLUMES].convex_query(p_convex.ptr(), p_convex.size(), points.ptr(), points.size(), cull_convex);
1144 return cull_convex.instances;
1145}
1146
1147void RendererSceneCull::instance_geometry_set_flag(RID p_instance, RS::InstanceFlags p_flags, bool p_enabled) {
1148 Instance *instance = instance_owner.get_or_null(p_instance);
1149 ERR_FAIL_COND(!instance);
1150
1151 //ERR_FAIL_COND(((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK));
1152
1153 switch (p_flags) {
1154 case RS::INSTANCE_FLAG_USE_BAKED_LIGHT: {
1155 instance->baked_light = p_enabled;
1156
1157 if (instance->scenario && instance->array_index >= 0) {
1158 InstanceData &idata = instance->scenario->instance_data[instance->array_index];
1159 if (instance->baked_light) {
1160 idata.flags |= InstanceData::FLAG_USES_BAKED_LIGHT;
1161 } else {
1162 idata.flags &= ~uint32_t(InstanceData::FLAG_USES_BAKED_LIGHT);
1163 }
1164 }
1165
1166 if ((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK && instance->base_data) {
1167 InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data);
1168 ERR_FAIL_NULL(geom->geometry_instance);
1169 geom->geometry_instance->set_use_baked_light(p_enabled);
1170 }
1171
1172 } break;
1173 case RS::INSTANCE_FLAG_USE_DYNAMIC_GI: {
1174 if (p_enabled == instance->dynamic_gi) {
1175 //bye, redundant
1176 return;
1177 }
1178
1179 if (instance->indexer_id.is_valid()) {
1180 _unpair_instance(instance);
1181 _instance_queue_update(instance, true, true);
1182 }
1183
1184 //once out of octree, can be changed
1185 instance->dynamic_gi = p_enabled;
1186
1187 if ((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK && instance->base_data) {
1188 InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data);
1189 ERR_FAIL_NULL(geom->geometry_instance);
1190 geom->geometry_instance->set_use_dynamic_gi(p_enabled);
1191 }
1192
1193 } break;
1194 case RS::INSTANCE_FLAG_DRAW_NEXT_FRAME_IF_VISIBLE: {
1195 instance->redraw_if_visible = p_enabled;
1196
1197 if (instance->scenario && instance->array_index >= 0) {
1198 InstanceData &idata = instance->scenario->instance_data[instance->array_index];
1199 if (instance->redraw_if_visible) {
1200 idata.flags |= InstanceData::FLAG_REDRAW_IF_VISIBLE;
1201 } else {
1202 idata.flags &= ~uint32_t(InstanceData::FLAG_REDRAW_IF_VISIBLE);
1203 }
1204 }
1205
1206 } break;
1207 case RS::INSTANCE_FLAG_IGNORE_OCCLUSION_CULLING: {
1208 instance->ignore_occlusion_culling = p_enabled;
1209
1210 if (instance->scenario && instance->array_index >= 0) {
1211 InstanceData &idata = instance->scenario->instance_data[instance->array_index];
1212 if (instance->ignore_occlusion_culling) {
1213 idata.flags |= InstanceData::FLAG_IGNORE_OCCLUSION_CULLING;
1214 } else {
1215 idata.flags &= ~uint32_t(InstanceData::FLAG_IGNORE_OCCLUSION_CULLING);
1216 }
1217 }
1218 } break;
1219 default: {
1220 }
1221 }
1222}
1223
1224void RendererSceneCull::instance_geometry_set_cast_shadows_setting(RID p_instance, RS::ShadowCastingSetting p_shadow_casting_setting) {
1225 Instance *instance = instance_owner.get_or_null(p_instance);
1226 ERR_FAIL_COND(!instance);
1227
1228 instance->cast_shadows = p_shadow_casting_setting;
1229
1230 if (instance->scenario && instance->array_index >= 0) {
1231 InstanceData &idata = instance->scenario->instance_data[instance->array_index];
1232
1233 if (instance->cast_shadows != RS::SHADOW_CASTING_SETTING_OFF) {
1234 idata.flags |= InstanceData::FLAG_CAST_SHADOWS;
1235 } else {
1236 idata.flags &= ~uint32_t(InstanceData::FLAG_CAST_SHADOWS);
1237 }
1238
1239 if (instance->cast_shadows == RS::SHADOW_CASTING_SETTING_SHADOWS_ONLY) {
1240 idata.flags |= InstanceData::FLAG_CAST_SHADOWS_ONLY;
1241 } else {
1242 idata.flags &= ~uint32_t(InstanceData::FLAG_CAST_SHADOWS_ONLY);
1243 }
1244 }
1245
1246 if ((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK && instance->base_data) {
1247 InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data);
1248 ERR_FAIL_NULL(geom->geometry_instance);
1249
1250 geom->geometry_instance->set_cast_double_sided_shadows(instance->cast_shadows == RS::SHADOW_CASTING_SETTING_DOUBLE_SIDED);
1251 }
1252
1253 _instance_queue_update(instance, false, true);
1254}
1255
1256void RendererSceneCull::instance_geometry_set_material_override(RID p_instance, RID p_material) {
1257 Instance *instance = instance_owner.get_or_null(p_instance);
1258 ERR_FAIL_COND(!instance);
1259
1260 instance->material_override = p_material;
1261 _instance_queue_update(instance, false, true);
1262
1263 if ((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK && instance->base_data) {
1264 InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data);
1265 ERR_FAIL_NULL(geom->geometry_instance);
1266 geom->geometry_instance->set_material_override(p_material);
1267 }
1268}
1269
1270void RendererSceneCull::instance_geometry_set_material_overlay(RID p_instance, RID p_material) {
1271 Instance *instance = instance_owner.get_or_null(p_instance);
1272 ERR_FAIL_COND(!instance);
1273
1274 instance->material_overlay = p_material;
1275 _instance_queue_update(instance, false, true);
1276
1277 if ((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK && instance->base_data) {
1278 InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data);
1279 ERR_FAIL_NULL(geom->geometry_instance);
1280 geom->geometry_instance->set_material_overlay(p_material);
1281 }
1282}
1283
1284void RendererSceneCull::instance_geometry_set_visibility_range(RID p_instance, float p_min, float p_max, float p_min_margin, float p_max_margin, RS::VisibilityRangeFadeMode p_fade_mode) {
1285 Instance *instance = instance_owner.get_or_null(p_instance);
1286 ERR_FAIL_COND(!instance);
1287
1288 instance->visibility_range_begin = p_min;
1289 instance->visibility_range_end = p_max;
1290 instance->visibility_range_begin_margin = p_min_margin;
1291 instance->visibility_range_end_margin = p_max_margin;
1292 instance->visibility_range_fade_mode = p_fade_mode;
1293
1294 _update_instance_visibility_dependencies(instance);
1295
1296 if (instance->scenario && instance->visibility_index != -1) {
1297 InstanceVisibilityData &vd = instance->scenario->instance_visibility[instance->visibility_index];
1298 vd.range_begin = instance->visibility_range_begin;
1299 vd.range_end = instance->visibility_range_end;
1300 vd.range_begin_margin = instance->visibility_range_begin_margin;
1301 vd.range_end_margin = instance->visibility_range_end_margin;
1302 vd.fade_mode = p_fade_mode;
1303 }
1304}
1305
1306void RendererSceneCull::instance_set_visibility_parent(RID p_instance, RID p_parent_instance) {
1307 Instance *instance = instance_owner.get_or_null(p_instance);
1308 ERR_FAIL_COND(!instance);
1309
1310 Instance *old_parent = instance->visibility_parent;
1311 if (old_parent) {
1312 old_parent->visibility_dependencies.erase(instance);
1313 instance->visibility_parent = nullptr;
1314 _update_instance_visibility_depth(old_parent);
1315 }
1316
1317 Instance *parent = instance_owner.get_or_null(p_parent_instance);
1318 ERR_FAIL_COND(p_parent_instance.is_valid() && !parent);
1319
1320 if (parent) {
1321 parent->visibility_dependencies.insert(instance);
1322 instance->visibility_parent = parent;
1323
1324 bool cycle_detected = _update_instance_visibility_depth(parent);
1325 if (cycle_detected) {
1326 ERR_PRINT("Cycle detected in the visibility dependencies tree. The latest change to visibility_parent will have no effect.");
1327 parent->visibility_dependencies.erase(instance);
1328 instance->visibility_parent = nullptr;
1329 }
1330 }
1331
1332 _update_instance_visibility_dependencies(instance);
1333}
1334
1335bool RendererSceneCull::_update_instance_visibility_depth(Instance *p_instance) {
1336 bool cycle_detected = false;
1337 HashSet<Instance *> traversed_nodes;
1338
1339 {
1340 Instance *instance = p_instance;
1341 while (instance) {
1342 if (!instance->visibility_dependencies.is_empty()) {
1343 uint32_t depth = 0;
1344 for (const Instance *E : instance->visibility_dependencies) {
1345 depth = MAX(depth, E->visibility_dependencies_depth);
1346 }
1347 instance->visibility_dependencies_depth = depth + 1;
1348 } else {
1349 instance->visibility_dependencies_depth = 0;
1350 }
1351
1352 if (instance->scenario && instance->visibility_index != -1) {
1353 instance->scenario->instance_visibility.move(instance->visibility_index, instance->visibility_dependencies_depth);
1354 }
1355
1356 traversed_nodes.insert(instance);
1357
1358 instance = instance->visibility_parent;
1359 if (traversed_nodes.has(instance)) {
1360 cycle_detected = true;
1361 break;
1362 }
1363 }
1364 }
1365
1366 return cycle_detected;
1367}
1368
1369void RendererSceneCull::_update_instance_visibility_dependencies(Instance *p_instance) {
1370 bool is_geometry_instance = ((1 << p_instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) && p_instance->base_data;
1371 bool has_visibility_range = p_instance->visibility_range_begin > 0.0 || p_instance->visibility_range_end > 0.0;
1372 bool needs_visibility_cull = has_visibility_range && is_geometry_instance && p_instance->array_index != -1;
1373
1374 if (!needs_visibility_cull && p_instance->visibility_index != -1) {
1375 p_instance->scenario->instance_visibility.remove_at(p_instance->visibility_index);
1376 p_instance->visibility_index = -1;
1377 } else if (needs_visibility_cull && p_instance->visibility_index == -1) {
1378 InstanceVisibilityData vd;
1379 vd.instance = p_instance;
1380 vd.range_begin = p_instance->visibility_range_begin;
1381 vd.range_end = p_instance->visibility_range_end;
1382 vd.range_begin_margin = p_instance->visibility_range_begin_margin;
1383 vd.range_end_margin = p_instance->visibility_range_end_margin;
1384 vd.position = p_instance->transformed_aabb.get_center();
1385 vd.array_index = p_instance->array_index;
1386 vd.fade_mode = p_instance->visibility_range_fade_mode;
1387
1388 p_instance->scenario->instance_visibility.insert(vd, p_instance->visibility_dependencies_depth);
1389 }
1390
1391 if (p_instance->scenario && p_instance->array_index != -1) {
1392 InstanceData &idata = p_instance->scenario->instance_data[p_instance->array_index];
1393 idata.visibility_index = p_instance->visibility_index;
1394
1395 if (is_geometry_instance) {
1396 if (has_visibility_range && p_instance->visibility_range_fade_mode == RS::VISIBILITY_RANGE_FADE_SELF) {
1397 bool begin_enabled = p_instance->visibility_range_begin > 0.0f;
1398 float begin_min = p_instance->visibility_range_begin - p_instance->visibility_range_begin_margin;
1399 float begin_max = p_instance->visibility_range_begin + p_instance->visibility_range_begin_margin;
1400 bool end_enabled = p_instance->visibility_range_end > 0.0f;
1401 float end_min = p_instance->visibility_range_end - p_instance->visibility_range_end_margin;
1402 float end_max = p_instance->visibility_range_end + p_instance->visibility_range_end_margin;
1403 idata.instance_geometry->set_fade_range(begin_enabled, begin_min, begin_max, end_enabled, end_min, end_max);
1404 } else {
1405 idata.instance_geometry->set_fade_range(false, 0.0f, 0.0f, false, 0.0f, 0.0f);
1406 }
1407 }
1408
1409 if ((has_visibility_range || p_instance->visibility_parent) && (p_instance->visibility_index == -1 || p_instance->visibility_dependencies_depth == 0)) {
1410 idata.flags |= InstanceData::FLAG_VISIBILITY_DEPENDENCY_NEEDS_CHECK;
1411 } else {
1412 idata.flags &= ~InstanceData::FLAG_VISIBILITY_DEPENDENCY_NEEDS_CHECK;
1413 }
1414
1415 if (p_instance->visibility_parent) {
1416 idata.parent_array_index = p_instance->visibility_parent->array_index;
1417 } else {
1418 idata.parent_array_index = -1;
1419 if (is_geometry_instance) {
1420 idata.instance_geometry->set_parent_fade_alpha(1.0f);
1421 }
1422 }
1423 }
1424}
1425
1426void RendererSceneCull::instance_geometry_set_lightmap(RID p_instance, RID p_lightmap, const Rect2 &p_lightmap_uv_scale, int p_slice_index) {
1427 Instance *instance = instance_owner.get_or_null(p_instance);
1428 ERR_FAIL_COND(!instance);
1429
1430 if (instance->lightmap) {
1431 InstanceLightmapData *lightmap_data = static_cast<InstanceLightmapData *>(((Instance *)instance->lightmap)->base_data);
1432 lightmap_data->users.erase(instance);
1433 instance->lightmap = nullptr;
1434 }
1435
1436 Instance *lightmap_instance = instance_owner.get_or_null(p_lightmap);
1437
1438 instance->lightmap = lightmap_instance;
1439 instance->lightmap_uv_scale = p_lightmap_uv_scale;
1440 instance->lightmap_slice_index = p_slice_index;
1441
1442 RID lightmap_instance_rid;
1443
1444 if (lightmap_instance) {
1445 InstanceLightmapData *lightmap_data = static_cast<InstanceLightmapData *>(lightmap_instance->base_data);
1446 lightmap_data->users.insert(instance);
1447 lightmap_instance_rid = lightmap_data->instance;
1448 }
1449
1450 if ((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK && instance->base_data) {
1451 InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data);
1452 ERR_FAIL_NULL(geom->geometry_instance);
1453 geom->geometry_instance->set_use_lightmap(lightmap_instance_rid, p_lightmap_uv_scale, p_slice_index);
1454 }
1455}
1456
1457void RendererSceneCull::instance_geometry_set_lod_bias(RID p_instance, float p_lod_bias) {
1458 Instance *instance = instance_owner.get_or_null(p_instance);
1459 ERR_FAIL_COND(!instance);
1460
1461 instance->lod_bias = p_lod_bias;
1462
1463 if ((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK && instance->base_data) {
1464 InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data);
1465 ERR_FAIL_NULL(geom->geometry_instance);
1466 geom->geometry_instance->set_lod_bias(p_lod_bias);
1467 }
1468}
1469
1470void RendererSceneCull::instance_geometry_set_shader_parameter(RID p_instance, const StringName &p_parameter, const Variant &p_value) {
1471 Instance *instance = instance_owner.get_or_null(p_instance);
1472 ERR_FAIL_COND(!instance);
1473
1474 ERR_FAIL_COND(p_value.get_type() == Variant::OBJECT);
1475
1476 HashMap<StringName, Instance::InstanceShaderParameter>::Iterator E = instance->instance_shader_uniforms.find(p_parameter);
1477
1478 if (!E) {
1479 Instance::InstanceShaderParameter isp;
1480 isp.index = -1;
1481 isp.info = PropertyInfo();
1482 isp.value = p_value;
1483 instance->instance_shader_uniforms[p_parameter] = isp;
1484 } else {
1485 E->value.value = p_value;
1486 if (E->value.index >= 0 && instance->instance_allocated_shader_uniforms) {
1487 int flags_count = 0;
1488 if (E->value.info.hint == PROPERTY_HINT_FLAGS) {
1489 // A small hack to detect boolean flags count and prevent overhead.
1490 switch (E->value.info.hint_string.length()) {
1491 case 3: // "x,y"
1492 flags_count = 1;
1493 break;
1494 case 5: // "x,y,z"
1495 flags_count = 2;
1496 break;
1497 case 7: // "x,y,z,w"
1498 flags_count = 3;
1499 break;
1500 }
1501 }
1502 //update directly
1503 RSG::material_storage->global_shader_parameters_instance_update(p_instance, E->value.index, p_value, flags_count);
1504 }
1505 }
1506}
1507
1508Variant RendererSceneCull::instance_geometry_get_shader_parameter(RID p_instance, const StringName &p_parameter) const {
1509 const Instance *instance = const_cast<RendererSceneCull *>(this)->instance_owner.get_or_null(p_instance);
1510 ERR_FAIL_COND_V(!instance, Variant());
1511
1512 if (instance->instance_shader_uniforms.has(p_parameter)) {
1513 return instance->instance_shader_uniforms[p_parameter].value;
1514 }
1515 return Variant();
1516}
1517
1518Variant RendererSceneCull::instance_geometry_get_shader_parameter_default_value(RID p_instance, const StringName &p_parameter) const {
1519 const Instance *instance = const_cast<RendererSceneCull *>(this)->instance_owner.get_or_null(p_instance);
1520 ERR_FAIL_COND_V(!instance, Variant());
1521
1522 if (instance->instance_shader_uniforms.has(p_parameter)) {
1523 return instance->instance_shader_uniforms[p_parameter].default_value;
1524 }
1525 return Variant();
1526}
1527
1528void RendererSceneCull::instance_geometry_get_shader_parameter_list(RID p_instance, List<PropertyInfo> *p_parameters) const {
1529 const Instance *instance = const_cast<RendererSceneCull *>(this)->instance_owner.get_or_null(p_instance);
1530 ERR_FAIL_COND(!instance);
1531
1532 const_cast<RendererSceneCull *>(this)->update_dirty_instances();
1533
1534 Vector<StringName> names;
1535 for (const KeyValue<StringName, Instance::InstanceShaderParameter> &E : instance->instance_shader_uniforms) {
1536 names.push_back(E.key);
1537 }
1538 names.sort_custom<StringName::AlphCompare>();
1539 for (int i = 0; i < names.size(); i++) {
1540 PropertyInfo pinfo = instance->instance_shader_uniforms[names[i]].info;
1541 p_parameters->push_back(pinfo);
1542 }
1543}
1544
1545void RendererSceneCull::_update_instance(Instance *p_instance) {
1546 p_instance->version++;
1547
1548 if (p_instance->base_type == RS::INSTANCE_LIGHT) {
1549 InstanceLightData *light = static_cast<InstanceLightData *>(p_instance->base_data);
1550
1551 RSG::light_storage->light_instance_set_transform(light->instance, p_instance->transform);
1552 RSG::light_storage->light_instance_set_aabb(light->instance, p_instance->transform.xform(p_instance->aabb));
1553 light->shadow_dirty = true;
1554
1555 RS::LightBakeMode bake_mode = RSG::light_storage->light_get_bake_mode(p_instance->base);
1556 if (RSG::light_storage->light_get_type(p_instance->base) != RS::LIGHT_DIRECTIONAL && bake_mode != light->bake_mode) {
1557 if (p_instance->visible && p_instance->scenario && light->bake_mode == RS::LIGHT_BAKE_DYNAMIC) {
1558 p_instance->scenario->dynamic_lights.erase(light->instance);
1559 }
1560
1561 light->bake_mode = bake_mode;
1562
1563 if (p_instance->visible && p_instance->scenario && light->bake_mode == RS::LIGHT_BAKE_DYNAMIC) {
1564 p_instance->scenario->dynamic_lights.push_back(light->instance);
1565 }
1566 }
1567
1568 uint32_t max_sdfgi_cascade = RSG::light_storage->light_get_max_sdfgi_cascade(p_instance->base);
1569 if (light->max_sdfgi_cascade != max_sdfgi_cascade) {
1570 light->max_sdfgi_cascade = max_sdfgi_cascade; //should most likely make sdfgi dirty in scenario
1571 }
1572 } else if (p_instance->base_type == RS::INSTANCE_REFLECTION_PROBE) {
1573 InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(p_instance->base_data);
1574
1575 RSG::light_storage->reflection_probe_instance_set_transform(reflection_probe->instance, p_instance->transform);
1576
1577 if (p_instance->scenario && p_instance->array_index >= 0) {
1578 InstanceData &idata = p_instance->scenario->instance_data[p_instance->array_index];
1579 idata.flags |= InstanceData::FLAG_REFLECTION_PROBE_DIRTY;
1580 }
1581 } else if (p_instance->base_type == RS::INSTANCE_DECAL) {
1582 InstanceDecalData *decal = static_cast<InstanceDecalData *>(p_instance->base_data);
1583
1584 RSG::texture_storage->decal_instance_set_transform(decal->instance, p_instance->transform);
1585 } else if (p_instance->base_type == RS::INSTANCE_LIGHTMAP) {
1586 InstanceLightmapData *lightmap = static_cast<InstanceLightmapData *>(p_instance->base_data);
1587
1588 RSG::light_storage->lightmap_instance_set_transform(lightmap->instance, p_instance->transform);
1589 } else if (p_instance->base_type == RS::INSTANCE_VOXEL_GI) {
1590 InstanceVoxelGIData *voxel_gi = static_cast<InstanceVoxelGIData *>(p_instance->base_data);
1591
1592 scene_render->voxel_gi_instance_set_transform_to_data(voxel_gi->probe_instance, p_instance->transform);
1593 } else if (p_instance->base_type == RS::INSTANCE_PARTICLES) {
1594 RSG::particles_storage->particles_set_emission_transform(p_instance->base, p_instance->transform);
1595 } else if (p_instance->base_type == RS::INSTANCE_PARTICLES_COLLISION) {
1596 InstanceParticlesCollisionData *collision = static_cast<InstanceParticlesCollisionData *>(p_instance->base_data);
1597
1598 //remove materials no longer used and un-own them
1599 if (RSG::particles_storage->particles_collision_is_heightfield(p_instance->base)) {
1600 heightfield_particle_colliders_update_list.insert(p_instance);
1601 }
1602 RSG::particles_storage->particles_collision_instance_set_transform(collision->instance, p_instance->transform);
1603 } else if (p_instance->base_type == RS::INSTANCE_FOG_VOLUME) {
1604 InstanceFogVolumeData *volume = static_cast<InstanceFogVolumeData *>(p_instance->base_data);
1605 scene_render->fog_volume_instance_set_transform(volume->instance, p_instance->transform);
1606 } else if (p_instance->base_type == RS::INSTANCE_OCCLUDER) {
1607 if (p_instance->scenario) {
1608 RendererSceneOcclusionCull::get_singleton()->scenario_set_instance(p_instance->scenario->self, p_instance->self, p_instance->base, p_instance->transform, p_instance->visible);
1609 }
1610 }
1611
1612 if (!p_instance->aabb.has_surface()) {
1613 return;
1614 }
1615
1616 if (p_instance->base_type == RS::INSTANCE_LIGHTMAP) {
1617 //if this moved, update the captured objects
1618 InstanceLightmapData *lightmap_data = static_cast<InstanceLightmapData *>(p_instance->base_data);
1619 //erase dependencies, since no longer a lightmap
1620
1621 for (Instance *E : lightmap_data->geometries) {
1622 Instance *geom = E;
1623 _instance_queue_update(geom, true, false);
1624 }
1625 }
1626
1627 AABB new_aabb;
1628 new_aabb = p_instance->transform.xform(p_instance->aabb);
1629 p_instance->transformed_aabb = new_aabb;
1630
1631 if ((1 << p_instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) {
1632 InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(p_instance->base_data);
1633 //make sure lights are updated if it casts shadow
1634
1635 if (geom->can_cast_shadows) {
1636 for (const Instance *E : geom->lights) {
1637 InstanceLightData *light = static_cast<InstanceLightData *>(E->base_data);
1638 light->shadow_dirty = true;
1639 }
1640 }
1641
1642 if (!p_instance->lightmap && geom->lightmap_captures.size()) {
1643 //affected by lightmap captures, must update capture info!
1644 _update_instance_lightmap_captures(p_instance);
1645 } else {
1646 if (!p_instance->lightmap_sh.is_empty()) {
1647 p_instance->lightmap_sh.clear(); //don't need SH
1648 p_instance->lightmap_target_sh.clear(); //don't need SH
1649 ERR_FAIL_NULL(geom->geometry_instance);
1650 geom->geometry_instance->set_lightmap_capture(nullptr);
1651 }
1652 }
1653
1654 ERR_FAIL_NULL(geom->geometry_instance);
1655 geom->geometry_instance->set_transform(p_instance->transform, p_instance->aabb, p_instance->transformed_aabb);
1656 }
1657
1658 // note: we had to remove is equal approx check here, it meant that det == 0.000004 won't work, which is the case for some of our scenes.
1659 if (p_instance->scenario == nullptr || !p_instance->visible || p_instance->transform.basis.determinant() == 0) {
1660 p_instance->prev_transformed_aabb = p_instance->transformed_aabb;
1661 return;
1662 }
1663
1664 //quantize to improve moving object performance
1665 AABB bvh_aabb = p_instance->transformed_aabb;
1666
1667 if (p_instance->indexer_id.is_valid() && bvh_aabb != p_instance->prev_transformed_aabb) {
1668 //assume motion, see if bounds need to be quantized
1669 AABB motion_aabb = bvh_aabb.merge(p_instance->prev_transformed_aabb);
1670 float motion_longest_axis = motion_aabb.get_longest_axis_size();
1671 float longest_axis = p_instance->transformed_aabb.get_longest_axis_size();
1672
1673 if (motion_longest_axis < longest_axis * 2) {
1674 //moved but not a lot, use motion aabb quantizing
1675 float quantize_size = Math::pow(2.0, Math::ceil(Math::log(motion_longest_axis) / Math::log(2.0))) * 0.5; //one fifth
1676 bvh_aabb.quantize(quantize_size);
1677 }
1678 }
1679
1680 if (!p_instance->indexer_id.is_valid()) {
1681 if ((1 << p_instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) {
1682 p_instance->indexer_id = p_instance->scenario->indexers[Scenario::INDEXER_GEOMETRY].insert(bvh_aabb, p_instance);
1683 } else {
1684 p_instance->indexer_id = p_instance->scenario->indexers[Scenario::INDEXER_VOLUMES].insert(bvh_aabb, p_instance);
1685 }
1686
1687 p_instance->array_index = p_instance->scenario->instance_data.size();
1688 InstanceData idata;
1689 idata.instance = p_instance;
1690 idata.layer_mask = p_instance->layer_mask;
1691 idata.flags = p_instance->base_type; //changing it means de-indexing, so this never needs to be changed later
1692 idata.base_rid = p_instance->base;
1693 idata.parent_array_index = p_instance->visibility_parent ? p_instance->visibility_parent->array_index : -1;
1694 idata.visibility_index = p_instance->visibility_index;
1695
1696 for (Instance *E : p_instance->visibility_dependencies) {
1697 Instance *dep_instance = E;
1698 if (dep_instance->array_index != -1) {
1699 dep_instance->scenario->instance_data[dep_instance->array_index].parent_array_index = p_instance->array_index;
1700 }
1701 }
1702
1703 switch (p_instance->base_type) {
1704 case RS::INSTANCE_MESH:
1705 case RS::INSTANCE_MULTIMESH:
1706 case RS::INSTANCE_PARTICLES: {
1707 InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(p_instance->base_data);
1708 idata.instance_geometry = geom->geometry_instance;
1709 } break;
1710 case RS::INSTANCE_LIGHT: {
1711 InstanceLightData *light_data = static_cast<InstanceLightData *>(p_instance->base_data);
1712 idata.instance_data_rid = light_data->instance.get_id();
1713 light_data->uses_projector = RSG::light_storage->light_has_projector(p_instance->base);
1714 light_data->uses_softshadow = RSG::light_storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_SIZE) > CMP_EPSILON;
1715
1716 } break;
1717 case RS::INSTANCE_REFLECTION_PROBE: {
1718 idata.instance_data_rid = static_cast<InstanceReflectionProbeData *>(p_instance->base_data)->instance.get_id();
1719 } break;
1720 case RS::INSTANCE_DECAL: {
1721 idata.instance_data_rid = static_cast<InstanceDecalData *>(p_instance->base_data)->instance.get_id();
1722 } break;
1723 case RS::INSTANCE_LIGHTMAP: {
1724 idata.instance_data_rid = static_cast<InstanceLightmapData *>(p_instance->base_data)->instance.get_id();
1725 } break;
1726 case RS::INSTANCE_VOXEL_GI: {
1727 idata.instance_data_rid = static_cast<InstanceVoxelGIData *>(p_instance->base_data)->probe_instance.get_id();
1728 } break;
1729 case RS::INSTANCE_FOG_VOLUME: {
1730 idata.instance_data_rid = static_cast<InstanceFogVolumeData *>(p_instance->base_data)->instance.get_id();
1731 } break;
1732 case RS::INSTANCE_VISIBLITY_NOTIFIER: {
1733 idata.visibility_notifier = static_cast<InstanceVisibilityNotifierData *>(p_instance->base_data);
1734 } break;
1735 default: {
1736 }
1737 }
1738
1739 if (p_instance->base_type == RS::INSTANCE_REFLECTION_PROBE) {
1740 //always dirty when added
1741 idata.flags |= InstanceData::FLAG_REFLECTION_PROBE_DIRTY;
1742 }
1743 if (p_instance->cast_shadows != RS::SHADOW_CASTING_SETTING_OFF) {
1744 idata.flags |= InstanceData::FLAG_CAST_SHADOWS;
1745 }
1746 if (p_instance->cast_shadows == RS::SHADOW_CASTING_SETTING_SHADOWS_ONLY) {
1747 idata.flags |= InstanceData::FLAG_CAST_SHADOWS_ONLY;
1748 }
1749 if (p_instance->redraw_if_visible) {
1750 idata.flags |= InstanceData::FLAG_REDRAW_IF_VISIBLE;
1751 }
1752 // dirty flags should not be set here, since no pairing has happened
1753 if (p_instance->baked_light) {
1754 idata.flags |= InstanceData::FLAG_USES_BAKED_LIGHT;
1755 }
1756 if (p_instance->mesh_instance.is_valid()) {
1757 idata.flags |= InstanceData::FLAG_USES_MESH_INSTANCE;
1758 }
1759 if (p_instance->ignore_occlusion_culling) {
1760 idata.flags |= InstanceData::FLAG_IGNORE_OCCLUSION_CULLING;
1761 }
1762 if (p_instance->ignore_all_culling) {
1763 idata.flags |= InstanceData::FLAG_IGNORE_ALL_CULLING;
1764 }
1765
1766 p_instance->scenario->instance_data.push_back(idata);
1767 p_instance->scenario->instance_aabbs.push_back(InstanceBounds(p_instance->transformed_aabb));
1768 _update_instance_visibility_dependencies(p_instance);
1769 } else {
1770 if ((1 << p_instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) {
1771 p_instance->scenario->indexers[Scenario::INDEXER_GEOMETRY].update(p_instance->indexer_id, bvh_aabb);
1772 } else {
1773 p_instance->scenario->indexers[Scenario::INDEXER_VOLUMES].update(p_instance->indexer_id, bvh_aabb);
1774 }
1775 p_instance->scenario->instance_aabbs[p_instance->array_index] = InstanceBounds(p_instance->transformed_aabb);
1776 }
1777
1778 if (p_instance->visibility_index != -1) {
1779 p_instance->scenario->instance_visibility[p_instance->visibility_index].position = p_instance->transformed_aabb.get_center();
1780 }
1781
1782 //move instance and repair
1783 pair_pass++;
1784
1785 PairInstances pair;
1786
1787 pair.instance = p_instance;
1788 pair.pair_allocator = &pair_allocator;
1789 pair.pair_pass = pair_pass;
1790 pair.pair_mask = 0;
1791 pair.cull_mask = 0xFFFFFFFF;
1792
1793 if ((1 << p_instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) {
1794 pair.pair_mask |= 1 << RS::INSTANCE_LIGHT;
1795 pair.pair_mask |= 1 << RS::INSTANCE_VOXEL_GI;
1796 pair.pair_mask |= 1 << RS::INSTANCE_LIGHTMAP;
1797 if (p_instance->base_type == RS::INSTANCE_PARTICLES) {
1798 pair.pair_mask |= 1 << RS::INSTANCE_PARTICLES_COLLISION;
1799 }
1800
1801 pair.pair_mask |= geometry_instance_pair_mask;
1802
1803 pair.bvh2 = &p_instance->scenario->indexers[Scenario::INDEXER_VOLUMES];
1804 } else if (p_instance->base_type == RS::INSTANCE_LIGHT) {
1805 pair.pair_mask |= RS::INSTANCE_GEOMETRY_MASK;
1806 pair.bvh = &p_instance->scenario->indexers[Scenario::INDEXER_GEOMETRY];
1807
1808 if (RSG::light_storage->light_get_bake_mode(p_instance->base) == RS::LIGHT_BAKE_DYNAMIC) {
1809 pair.pair_mask |= (1 << RS::INSTANCE_VOXEL_GI);
1810 pair.bvh2 = &p_instance->scenario->indexers[Scenario::INDEXER_VOLUMES];
1811 }
1812 pair.cull_mask = RSG::light_storage->light_get_cull_mask(p_instance->base);
1813 } else if (geometry_instance_pair_mask & (1 << RS::INSTANCE_REFLECTION_PROBE) && (p_instance->base_type == RS::INSTANCE_REFLECTION_PROBE)) {
1814 pair.pair_mask = RS::INSTANCE_GEOMETRY_MASK;
1815 pair.bvh = &p_instance->scenario->indexers[Scenario::INDEXER_GEOMETRY];
1816 } else if (geometry_instance_pair_mask & (1 << RS::INSTANCE_DECAL) && (p_instance->base_type == RS::INSTANCE_DECAL)) {
1817 pair.pair_mask = RS::INSTANCE_GEOMETRY_MASK;
1818 pair.bvh = &p_instance->scenario->indexers[Scenario::INDEXER_GEOMETRY];
1819 pair.cull_mask = RSG::texture_storage->decal_get_cull_mask(p_instance->base);
1820 } else if (p_instance->base_type == RS::INSTANCE_PARTICLES_COLLISION) {
1821 pair.pair_mask = (1 << RS::INSTANCE_PARTICLES);
1822 pair.bvh = &p_instance->scenario->indexers[Scenario::INDEXER_GEOMETRY];
1823 } else if (p_instance->base_type == RS::INSTANCE_VOXEL_GI) {
1824 //lights and geometries
1825 pair.pair_mask = RS::INSTANCE_GEOMETRY_MASK | (1 << RS::INSTANCE_LIGHT);
1826 pair.bvh = &p_instance->scenario->indexers[Scenario::INDEXER_GEOMETRY];
1827 pair.bvh2 = &p_instance->scenario->indexers[Scenario::INDEXER_VOLUMES];
1828 }
1829
1830 pair.pair();
1831
1832 p_instance->prev_transformed_aabb = p_instance->transformed_aabb;
1833}
1834
1835void RendererSceneCull::_unpair_instance(Instance *p_instance) {
1836 if (!p_instance->indexer_id.is_valid()) {
1837 return; //nothing to do
1838 }
1839
1840 while (p_instance->pairs.first()) {
1841 InstancePair *pair = p_instance->pairs.first()->self();
1842 Instance *other_instance = p_instance == pair->a ? pair->b : pair->a;
1843 _instance_unpair(p_instance, other_instance);
1844 pair_allocator.free(pair);
1845 }
1846
1847 if ((1 << p_instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) {
1848 p_instance->scenario->indexers[Scenario::INDEXER_GEOMETRY].remove(p_instance->indexer_id);
1849 } else {
1850 p_instance->scenario->indexers[Scenario::INDEXER_VOLUMES].remove(p_instance->indexer_id);
1851 }
1852
1853 p_instance->indexer_id = DynamicBVH::ID();
1854
1855 //replace this by last
1856 int32_t swap_with_index = p_instance->scenario->instance_data.size() - 1;
1857 if (swap_with_index != p_instance->array_index) {
1858 Instance *swapped_instance = p_instance->scenario->instance_data[swap_with_index].instance;
1859 swapped_instance->array_index = p_instance->array_index; //swap
1860 p_instance->scenario->instance_data[p_instance->array_index] = p_instance->scenario->instance_data[swap_with_index];
1861 p_instance->scenario->instance_aabbs[p_instance->array_index] = p_instance->scenario->instance_aabbs[swap_with_index];
1862
1863 if (swapped_instance->visibility_index != -1) {
1864 swapped_instance->scenario->instance_visibility[swapped_instance->visibility_index].array_index = swapped_instance->array_index;
1865 }
1866
1867 for (Instance *E : swapped_instance->visibility_dependencies) {
1868 Instance *dep_instance = E;
1869 if (dep_instance != p_instance && dep_instance->array_index != -1) {
1870 dep_instance->scenario->instance_data[dep_instance->array_index].parent_array_index = swapped_instance->array_index;
1871 }
1872 }
1873 }
1874
1875 // pop last
1876 p_instance->scenario->instance_data.pop_back();
1877 p_instance->scenario->instance_aabbs.pop_back();
1878
1879 //uninitialize
1880 p_instance->array_index = -1;
1881 if ((1 << p_instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) {
1882 // Clear these now because the InstanceData containing the dirty flags is gone
1883 InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(p_instance->base_data);
1884 ERR_FAIL_NULL(geom->geometry_instance);
1885
1886 geom->geometry_instance->pair_light_instances(nullptr, 0);
1887 geom->geometry_instance->pair_reflection_probe_instances(nullptr, 0);
1888 geom->geometry_instance->pair_decal_instances(nullptr, 0);
1889 geom->geometry_instance->pair_voxel_gi_instances(nullptr, 0);
1890 }
1891
1892 for (Instance *E : p_instance->visibility_dependencies) {
1893 Instance *dep_instance = E;
1894 if (dep_instance->array_index != -1) {
1895 dep_instance->scenario->instance_data[dep_instance->array_index].parent_array_index = -1;
1896 if ((1 << dep_instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) {
1897 dep_instance->scenario->instance_data[dep_instance->array_index].instance_geometry->set_parent_fade_alpha(1.0f);
1898 }
1899 }
1900 }
1901
1902 _update_instance_visibility_dependencies(p_instance);
1903}
1904
1905void RendererSceneCull::_update_instance_aabb(Instance *p_instance) {
1906 AABB new_aabb;
1907
1908 ERR_FAIL_COND(p_instance->base_type != RS::INSTANCE_NONE && !p_instance->base.is_valid());
1909
1910 switch (p_instance->base_type) {
1911 case RenderingServer::INSTANCE_NONE: {
1912 // do nothing
1913 } break;
1914 case RenderingServer::INSTANCE_MESH: {
1915 if (p_instance->custom_aabb) {
1916 new_aabb = *p_instance->custom_aabb;
1917 } else {
1918 new_aabb = RSG::mesh_storage->mesh_get_aabb(p_instance->base, p_instance->skeleton);
1919 }
1920
1921 } break;
1922
1923 case RenderingServer::INSTANCE_MULTIMESH: {
1924 if (p_instance->custom_aabb) {
1925 new_aabb = *p_instance->custom_aabb;
1926 } else {
1927 new_aabb = RSG::mesh_storage->multimesh_get_aabb(p_instance->base);
1928 }
1929
1930 } break;
1931 case RenderingServer::INSTANCE_PARTICLES: {
1932 if (p_instance->custom_aabb) {
1933 new_aabb = *p_instance->custom_aabb;
1934 } else {
1935 new_aabb = RSG::particles_storage->particles_get_aabb(p_instance->base);
1936 }
1937
1938 } break;
1939 case RenderingServer::INSTANCE_PARTICLES_COLLISION: {
1940 new_aabb = RSG::particles_storage->particles_collision_get_aabb(p_instance->base);
1941
1942 } break;
1943 case RenderingServer::INSTANCE_FOG_VOLUME: {
1944 new_aabb = RSG::fog->fog_volume_get_aabb(p_instance->base);
1945 } break;
1946 case RenderingServer::INSTANCE_VISIBLITY_NOTIFIER: {
1947 new_aabb = RSG::utilities->visibility_notifier_get_aabb(p_instance->base);
1948 } break;
1949 case RenderingServer::INSTANCE_LIGHT: {
1950 new_aabb = RSG::light_storage->light_get_aabb(p_instance->base);
1951
1952 } break;
1953 case RenderingServer::INSTANCE_REFLECTION_PROBE: {
1954 new_aabb = RSG::light_storage->reflection_probe_get_aabb(p_instance->base);
1955
1956 } break;
1957 case RenderingServer::INSTANCE_DECAL: {
1958 new_aabb = RSG::texture_storage->decal_get_aabb(p_instance->base);
1959
1960 } break;
1961 case RenderingServer::INSTANCE_VOXEL_GI: {
1962 new_aabb = RSG::gi->voxel_gi_get_bounds(p_instance->base);
1963
1964 } break;
1965 case RenderingServer::INSTANCE_LIGHTMAP: {
1966 new_aabb = RSG::light_storage->lightmap_get_aabb(p_instance->base);
1967
1968 } break;
1969 default: {
1970 }
1971 }
1972
1973 if (p_instance->extra_margin) {
1974 new_aabb.grow_by(p_instance->extra_margin);
1975 }
1976
1977 p_instance->aabb = new_aabb;
1978}
1979
1980void RendererSceneCull::_update_instance_lightmap_captures(Instance *p_instance) {
1981 bool first_set = p_instance->lightmap_sh.size() == 0;
1982 p_instance->lightmap_sh.resize(9); //using SH
1983 p_instance->lightmap_target_sh.resize(9); //using SH
1984 Color *instance_sh = p_instance->lightmap_target_sh.ptrw();
1985 bool inside = false;
1986 Color accum_sh[9];
1987 float accum_blend = 0.0;
1988
1989 InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(p_instance->base_data);
1990 for (Instance *E : geom->lightmap_captures) {
1991 Instance *lightmap = E;
1992
1993 bool interior = RSG::light_storage->lightmap_is_interior(lightmap->base);
1994
1995 if (inside && !interior) {
1996 continue; //we are inside, ignore exteriors
1997 }
1998
1999 Transform3D to_bounds = lightmap->transform.affine_inverse();
2000 Vector3 center = p_instance->transform.xform(p_instance->aabb.get_center()); //use aabb center
2001
2002 Vector3 lm_pos = to_bounds.xform(center);
2003
2004 AABB bounds = RSG::light_storage->lightmap_get_aabb(lightmap->base);
2005 if (!bounds.has_point(lm_pos)) {
2006 continue; //not in this lightmap
2007 }
2008
2009 Color sh[9];
2010 RSG::light_storage->lightmap_tap_sh_light(lightmap->base, lm_pos, sh);
2011
2012 //rotate it
2013 Basis rot = lightmap->transform.basis.orthonormalized();
2014 for (int i = 0; i < 3; i++) {
2015 real_t csh[9];
2016 for (int j = 0; j < 9; j++) {
2017 csh[j] = sh[j][i];
2018 }
2019 rot.rotate_sh(csh);
2020 for (int j = 0; j < 9; j++) {
2021 sh[j][i] = csh[j];
2022 }
2023 }
2024
2025 Vector3 inner_pos = ((lm_pos - bounds.position) / bounds.size) * 2.0 - Vector3(1.0, 1.0, 1.0);
2026
2027 real_t blend = MAX(inner_pos.x, MAX(inner_pos.y, inner_pos.z));
2028 //make blend more rounded
2029 blend = Math::lerp(inner_pos.length(), blend, blend);
2030 blend *= blend;
2031 blend = MAX(0.0, 1.0 - blend);
2032
2033 if (interior && !inside) {
2034 //do not blend, just replace
2035 for (int j = 0; j < 9; j++) {
2036 accum_sh[j] = sh[j] * blend;
2037 }
2038 accum_blend = blend;
2039 inside = true;
2040 } else {
2041 for (int j = 0; j < 9; j++) {
2042 accum_sh[j] += sh[j] * blend;
2043 }
2044 accum_blend += blend;
2045 }
2046 }
2047
2048 if (accum_blend > 0.0) {
2049 for (int j = 0; j < 9; j++) {
2050 instance_sh[j] = accum_sh[j] / accum_blend;
2051 if (first_set) {
2052 p_instance->lightmap_sh.write[j] = instance_sh[j];
2053 }
2054 }
2055 }
2056
2057 ERR_FAIL_NULL(geom->geometry_instance);
2058 geom->geometry_instance->set_lightmap_capture(p_instance->lightmap_sh.ptr());
2059}
2060
2061void RendererSceneCull::_light_instance_setup_directional_shadow(int p_shadow_index, Instance *p_instance, const Transform3D p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect) {
2062 InstanceLightData *light = static_cast<InstanceLightData *>(p_instance->base_data);
2063
2064 Transform3D light_transform = p_instance->transform;
2065 light_transform.orthonormalize(); //scale does not count on lights
2066
2067 real_t max_distance = p_cam_projection.get_z_far();
2068 real_t shadow_max = RSG::light_storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_SHADOW_MAX_DISTANCE);
2069 if (shadow_max > 0 && !p_cam_orthogonal) { //its impractical (and leads to unwanted behaviors) to set max distance in orthogonal camera
2070 max_distance = MIN(shadow_max, max_distance);
2071 }
2072 max_distance = MAX(max_distance, p_cam_projection.get_z_near() + 0.001);
2073 real_t min_distance = MIN(p_cam_projection.get_z_near(), max_distance);
2074
2075 real_t pancake_size = RSG::light_storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_SHADOW_PANCAKE_SIZE);
2076
2077 real_t range = max_distance - min_distance;
2078
2079 int splits = 0;
2080 switch (RSG::light_storage->light_directional_get_shadow_mode(p_instance->base)) {
2081 case RS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL:
2082 splits = 1;
2083 break;
2084 case RS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS:
2085 splits = 2;
2086 break;
2087 case RS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_4_SPLITS:
2088 splits = 4;
2089 break;
2090 }
2091
2092 real_t distances[5];
2093
2094 distances[0] = min_distance;
2095 for (int i = 0; i < splits; i++) {
2096 distances[i + 1] = min_distance + RSG::light_storage->light_get_param(p_instance->base, RS::LightParam(RS::LIGHT_PARAM_SHADOW_SPLIT_1_OFFSET + i)) * range;
2097 };
2098
2099 distances[splits] = max_distance;
2100
2101 real_t texture_size = RSG::light_storage->get_directional_light_shadow_size(light->instance);
2102
2103 bool overlap = RSG::light_storage->light_directional_get_blend_splits(p_instance->base);
2104
2105 cull.shadow_count = p_shadow_index + 1;
2106 cull.shadows[p_shadow_index].cascade_count = splits;
2107 cull.shadows[p_shadow_index].light_instance = light->instance;
2108
2109 for (int i = 0; i < splits; i++) {
2110 RENDER_TIMESTAMP("Cull DirectionalLight3D, Split " + itos(i));
2111
2112 // setup a camera matrix for that range!
2113 Projection camera_matrix;
2114
2115 real_t aspect = p_cam_projection.get_aspect();
2116
2117 if (p_cam_orthogonal) {
2118 Vector2 vp_he = p_cam_projection.get_viewport_half_extents();
2119
2120 camera_matrix.set_orthogonal(vp_he.y * 2.0, aspect, distances[(i == 0 || !overlap) ? i : i - 1], distances[i + 1], false);
2121 } else {
2122 real_t fov = p_cam_projection.get_fov(); //this is actually yfov, because set aspect tries to keep it
2123 camera_matrix.set_perspective(fov, aspect, distances[(i == 0 || !overlap) ? i : i - 1], distances[i + 1], true);
2124 }
2125
2126 //obtain the frustum endpoints
2127
2128 Vector3 endpoints[8]; // frustum plane endpoints
2129 bool res = camera_matrix.get_endpoints(p_cam_transform, endpoints);
2130 ERR_CONTINUE(!res);
2131
2132 // obtain the light frustum ranges (given endpoints)
2133
2134 Transform3D transform = light_transform; //discard scale and stabilize light
2135
2136 Vector3 x_vec = transform.basis.get_column(Vector3::AXIS_X).normalized();
2137 Vector3 y_vec = transform.basis.get_column(Vector3::AXIS_Y).normalized();
2138 Vector3 z_vec = transform.basis.get_column(Vector3::AXIS_Z).normalized();
2139 //z_vec points against the camera, like in default opengl
2140
2141 real_t x_min = 0.f, x_max = 0.f;
2142 real_t y_min = 0.f, y_max = 0.f;
2143 real_t z_min = 0.f, z_max = 0.f;
2144
2145 // FIXME: z_max_cam is defined, computed, but not used below when setting up
2146 // ortho_camera. Commented out for now to fix warnings but should be investigated.
2147 real_t x_min_cam = 0.f, x_max_cam = 0.f;
2148 real_t y_min_cam = 0.f, y_max_cam = 0.f;
2149 real_t z_min_cam = 0.f;
2150 //real_t z_max_cam = 0.f;
2151
2152 //real_t bias_scale = 1.0;
2153 //real_t aspect_bias_scale = 1.0;
2154
2155 //used for culling
2156
2157 for (int j = 0; j < 8; j++) {
2158 real_t d_x = x_vec.dot(endpoints[j]);
2159 real_t d_y = y_vec.dot(endpoints[j]);
2160 real_t d_z = z_vec.dot(endpoints[j]);
2161
2162 if (j == 0 || d_x < x_min) {
2163 x_min = d_x;
2164 }
2165 if (j == 0 || d_x > x_max) {
2166 x_max = d_x;
2167 }
2168
2169 if (j == 0 || d_y < y_min) {
2170 y_min = d_y;
2171 }
2172 if (j == 0 || d_y > y_max) {
2173 y_max = d_y;
2174 }
2175
2176 if (j == 0 || d_z < z_min) {
2177 z_min = d_z;
2178 }
2179 if (j == 0 || d_z > z_max) {
2180 z_max = d_z;
2181 }
2182 }
2183
2184 real_t radius = 0;
2185 real_t soft_shadow_expand = 0;
2186 Vector3 center;
2187
2188 {
2189 //camera viewport stuff
2190
2191 for (int j = 0; j < 8; j++) {
2192 center += endpoints[j];
2193 }
2194 center /= 8.0;
2195
2196 //center=x_vec*(x_max-x_min)*0.5 + y_vec*(y_max-y_min)*0.5 + z_vec*(z_max-z_min)*0.5;
2197
2198 for (int j = 0; j < 8; j++) {
2199 real_t d = center.distance_to(endpoints[j]);
2200 if (d > radius) {
2201 radius = d;
2202 }
2203 }
2204
2205 radius *= texture_size / (texture_size - 2.0); //add a texel by each side
2206
2207 z_min_cam = z_vec.dot(center) - radius;
2208
2209 {
2210 float soft_shadow_angle = RSG::light_storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_SIZE);
2211
2212 if (soft_shadow_angle > 0.0) {
2213 float z_range = (z_vec.dot(center) + radius + pancake_size) - z_min_cam;
2214 soft_shadow_expand = Math::tan(Math::deg_to_rad(soft_shadow_angle)) * z_range;
2215
2216 x_max += soft_shadow_expand;
2217 y_max += soft_shadow_expand;
2218
2219 x_min -= soft_shadow_expand;
2220 y_min -= soft_shadow_expand;
2221 }
2222 }
2223
2224 // This trick here is what stabilizes the shadow (make potential jaggies to not move)
2225 // at the cost of some wasted resolution. Still, the quality increase is very well worth it.
2226 const real_t unit = (radius + soft_shadow_expand) * 2.0 / texture_size;
2227 x_max_cam = Math::snapped(x_vec.dot(center) + radius + soft_shadow_expand, unit);
2228 x_min_cam = Math::snapped(x_vec.dot(center) - radius - soft_shadow_expand, unit);
2229 y_max_cam = Math::snapped(y_vec.dot(center) + radius + soft_shadow_expand, unit);
2230 y_min_cam = Math::snapped(y_vec.dot(center) - radius - soft_shadow_expand, unit);
2231 }
2232
2233 //now that we know all ranges, we can proceed to make the light frustum planes, for culling octree
2234
2235 Vector<Plane> light_frustum_planes;
2236 light_frustum_planes.resize(6);
2237
2238 //right/left
2239 light_frustum_planes.write[0] = Plane(x_vec, x_max);
2240 light_frustum_planes.write[1] = Plane(-x_vec, -x_min);
2241 //top/bottom
2242 light_frustum_planes.write[2] = Plane(y_vec, y_max);
2243 light_frustum_planes.write[3] = Plane(-y_vec, -y_min);
2244 //near/far
2245 light_frustum_planes.write[4] = Plane(z_vec, z_max + 1e6);
2246 light_frustum_planes.write[5] = Plane(-z_vec, -z_min); // z_min is ok, since casters further than far-light plane are not needed
2247
2248 // a pre pass will need to be needed to determine the actual z-near to be used
2249
2250 z_max = z_vec.dot(center) + radius + pancake_size;
2251
2252 {
2253 Projection ortho_camera;
2254 real_t half_x = (x_max_cam - x_min_cam) * 0.5;
2255 real_t half_y = (y_max_cam - y_min_cam) * 0.5;
2256
2257 ortho_camera.set_orthogonal(-half_x, half_x, -half_y, half_y, 0, (z_max - z_min_cam));
2258
2259 Vector2 uv_scale(1.0 / (x_max_cam - x_min_cam), 1.0 / (y_max_cam - y_min_cam));
2260
2261 Transform3D ortho_transform;
2262 ortho_transform.basis = transform.basis;
2263 ortho_transform.origin = x_vec * (x_min_cam + half_x) + y_vec * (y_min_cam + half_y) + z_vec * z_max;
2264
2265 cull.shadows[p_shadow_index].cascades[i].frustum = Frustum(light_frustum_planes);
2266 cull.shadows[p_shadow_index].cascades[i].projection = ortho_camera;
2267 cull.shadows[p_shadow_index].cascades[i].transform = ortho_transform;
2268 cull.shadows[p_shadow_index].cascades[i].zfar = z_max - z_min_cam;
2269 cull.shadows[p_shadow_index].cascades[i].split = distances[i + 1];
2270 cull.shadows[p_shadow_index].cascades[i].shadow_texel_size = radius * 2.0 / texture_size;
2271 cull.shadows[p_shadow_index].cascades[i].bias_scale = (z_max - z_min_cam);
2272 cull.shadows[p_shadow_index].cascades[i].range_begin = z_max;
2273 cull.shadows[p_shadow_index].cascades[i].uv_scale = uv_scale;
2274 }
2275 }
2276}
2277
2278bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, const Transform3D p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect, RID p_shadow_atlas, Scenario *p_scenario, float p_screen_mesh_lod_threshold, uint32_t p_visible_layers) {
2279 InstanceLightData *light = static_cast<InstanceLightData *>(p_instance->base_data);
2280
2281 Transform3D light_transform = p_instance->transform;
2282 light_transform.orthonormalize(); //scale does not count on lights
2283
2284 bool animated_material_found = false;
2285
2286 switch (RSG::light_storage->light_get_type(p_instance->base)) {
2287 case RS::LIGHT_DIRECTIONAL: {
2288 } break;
2289 case RS::LIGHT_OMNI: {
2290 RS::LightOmniShadowMode shadow_mode = RSG::light_storage->light_omni_get_shadow_mode(p_instance->base);
2291
2292 if (shadow_mode == RS::LIGHT_OMNI_SHADOW_DUAL_PARABOLOID || !RSG::light_storage->light_instances_can_render_shadow_cube()) {
2293 if (max_shadows_used + 2 > MAX_UPDATE_SHADOWS) {
2294 return true;
2295 }
2296 for (int i = 0; i < 2; i++) {
2297 //using this one ensures that raster deferred will have it
2298 RENDER_TIMESTAMP("Cull OmniLight3D Shadow Paraboloid, Half " + itos(i));
2299
2300 real_t radius = RSG::light_storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_RANGE);
2301
2302 real_t z = i == 0 ? -1 : 1;
2303 Vector<Plane> planes;
2304 planes.resize(6);
2305 planes.write[0] = light_transform.xform(Plane(Vector3(0, 0, z), radius));
2306 planes.write[1] = light_transform.xform(Plane(Vector3(1, 0, z).normalized(), radius));
2307 planes.write[2] = light_transform.xform(Plane(Vector3(-1, 0, z).normalized(), radius));
2308 planes.write[3] = light_transform.xform(Plane(Vector3(0, 1, z).normalized(), radius));
2309 planes.write[4] = light_transform.xform(Plane(Vector3(0, -1, z).normalized(), radius));
2310 planes.write[5] = light_transform.xform(Plane(Vector3(0, 0, -z), 0));
2311
2312 instance_shadow_cull_result.clear();
2313
2314 Vector<Vector3> points = Geometry3D::compute_convex_mesh_points(&planes[0], planes.size());
2315
2316 struct CullConvex {
2317 PagedArray<Instance *> *result;
2318 _FORCE_INLINE_ bool operator()(void *p_data) {
2319 Instance *p_instance = (Instance *)p_data;
2320 result->push_back(p_instance);
2321 return false;
2322 }
2323 };
2324
2325 CullConvex cull_convex;
2326 cull_convex.result = &instance_shadow_cull_result;
2327
2328 p_scenario->indexers[Scenario::INDEXER_GEOMETRY].convex_query(planes.ptr(), planes.size(), points.ptr(), points.size(), cull_convex);
2329
2330 RendererSceneRender::RenderShadowData &shadow_data = render_shadow_data[max_shadows_used++];
2331
2332 for (int j = 0; j < (int)instance_shadow_cull_result.size(); j++) {
2333 Instance *instance = instance_shadow_cull_result[j];
2334 if (!instance->visible || !((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) || !static_cast<InstanceGeometryData *>(instance->base_data)->can_cast_shadows || !(p_visible_layers & instance->layer_mask)) {
2335 continue;
2336 } else {
2337 if (static_cast<InstanceGeometryData *>(instance->base_data)->material_is_animated) {
2338 animated_material_found = true;
2339 }
2340
2341 if (instance->mesh_instance.is_valid()) {
2342 RSG::mesh_storage->mesh_instance_check_for_update(instance->mesh_instance);
2343 }
2344 }
2345
2346 shadow_data.instances.push_back(static_cast<InstanceGeometryData *>(instance->base_data)->geometry_instance);
2347 }
2348
2349 RSG::mesh_storage->update_mesh_instances();
2350
2351 RSG::light_storage->light_instance_set_shadow_transform(light->instance, Projection(), light_transform, radius, 0, i, 0);
2352 shadow_data.light = light->instance;
2353 shadow_data.pass = i;
2354 }
2355 } else { //shadow cube
2356
2357 if (max_shadows_used + 6 > MAX_UPDATE_SHADOWS) {
2358 return true;
2359 }
2360
2361 real_t radius = RSG::light_storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_RANGE);
2362 Projection cm;
2363 cm.set_perspective(90, 1, radius * 0.005f, radius);
2364
2365 for (int i = 0; i < 6; i++) {
2366 RENDER_TIMESTAMP("Cull OmniLight3D Shadow Cube, Side " + itos(i));
2367 //using this one ensures that raster deferred will have it
2368
2369 static const Vector3 view_normals[6] = {
2370 Vector3(+1, 0, 0),
2371 Vector3(-1, 0, 0),
2372 Vector3(0, -1, 0),
2373 Vector3(0, +1, 0),
2374 Vector3(0, 0, +1),
2375 Vector3(0, 0, -1)
2376 };
2377 static const Vector3 view_up[6] = {
2378 Vector3(0, -1, 0),
2379 Vector3(0, -1, 0),
2380 Vector3(0, 0, -1),
2381 Vector3(0, 0, +1),
2382 Vector3(0, -1, 0),
2383 Vector3(0, -1, 0)
2384 };
2385
2386 Transform3D xform = light_transform * Transform3D().looking_at(view_normals[i], view_up[i]);
2387
2388 Vector<Plane> planes = cm.get_projection_planes(xform);
2389
2390 instance_shadow_cull_result.clear();
2391
2392 Vector<Vector3> points = Geometry3D::compute_convex_mesh_points(&planes[0], planes.size());
2393
2394 struct CullConvex {
2395 PagedArray<Instance *> *result;
2396 _FORCE_INLINE_ bool operator()(void *p_data) {
2397 Instance *p_instance = (Instance *)p_data;
2398 result->push_back(p_instance);
2399 return false;
2400 }
2401 };
2402
2403 CullConvex cull_convex;
2404 cull_convex.result = &instance_shadow_cull_result;
2405
2406 p_scenario->indexers[Scenario::INDEXER_GEOMETRY].convex_query(planes.ptr(), planes.size(), points.ptr(), points.size(), cull_convex);
2407
2408 RendererSceneRender::RenderShadowData &shadow_data = render_shadow_data[max_shadows_used++];
2409
2410 for (int j = 0; j < (int)instance_shadow_cull_result.size(); j++) {
2411 Instance *instance = instance_shadow_cull_result[j];
2412 if (!instance->visible || !((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) || !static_cast<InstanceGeometryData *>(instance->base_data)->can_cast_shadows || !(p_visible_layers & instance->layer_mask)) {
2413 continue;
2414 } else {
2415 if (static_cast<InstanceGeometryData *>(instance->base_data)->material_is_animated) {
2416 animated_material_found = true;
2417 }
2418 if (instance->mesh_instance.is_valid()) {
2419 RSG::mesh_storage->mesh_instance_check_for_update(instance->mesh_instance);
2420 }
2421 }
2422
2423 shadow_data.instances.push_back(static_cast<InstanceGeometryData *>(instance->base_data)->geometry_instance);
2424 }
2425
2426 RSG::mesh_storage->update_mesh_instances();
2427 RSG::light_storage->light_instance_set_shadow_transform(light->instance, cm, xform, radius, 0, i, 0);
2428
2429 shadow_data.light = light->instance;
2430 shadow_data.pass = i;
2431 }
2432
2433 //restore the regular DP matrix
2434 //RSG::light_storage->light_instance_set_shadow_transform(light->instance, Projection(), light_transform, radius, 0, 0, 0);
2435 }
2436
2437 } break;
2438 case RS::LIGHT_SPOT: {
2439 RENDER_TIMESTAMP("Cull SpotLight3D Shadow");
2440
2441 if (max_shadows_used + 1 > MAX_UPDATE_SHADOWS) {
2442 return true;
2443 }
2444
2445 real_t radius = RSG::light_storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_RANGE);
2446 real_t angle = RSG::light_storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_SPOT_ANGLE);
2447
2448 Projection cm;
2449 cm.set_perspective(angle * 2.0, 1.0, 0.005f * radius, radius);
2450
2451 Vector<Plane> planes = cm.get_projection_planes(light_transform);
2452
2453 instance_shadow_cull_result.clear();
2454
2455 Vector<Vector3> points = Geometry3D::compute_convex_mesh_points(&planes[0], planes.size());
2456
2457 struct CullConvex {
2458 PagedArray<Instance *> *result;
2459 _FORCE_INLINE_ bool operator()(void *p_data) {
2460 Instance *p_instance = (Instance *)p_data;
2461 result->push_back(p_instance);
2462 return false;
2463 }
2464 };
2465
2466 CullConvex cull_convex;
2467 cull_convex.result = &instance_shadow_cull_result;
2468
2469 p_scenario->indexers[Scenario::INDEXER_GEOMETRY].convex_query(planes.ptr(), planes.size(), points.ptr(), points.size(), cull_convex);
2470
2471 RendererSceneRender::RenderShadowData &shadow_data = render_shadow_data[max_shadows_used++];
2472
2473 for (int j = 0; j < (int)instance_shadow_cull_result.size(); j++) {
2474 Instance *instance = instance_shadow_cull_result[j];
2475 if (!instance->visible || !((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) || !static_cast<InstanceGeometryData *>(instance->base_data)->can_cast_shadows || !(p_visible_layers & instance->layer_mask)) {
2476 continue;
2477 } else {
2478 if (static_cast<InstanceGeometryData *>(instance->base_data)->material_is_animated) {
2479 animated_material_found = true;
2480 }
2481
2482 if (instance->mesh_instance.is_valid()) {
2483 RSG::mesh_storage->mesh_instance_check_for_update(instance->mesh_instance);
2484 }
2485 }
2486 shadow_data.instances.push_back(static_cast<InstanceGeometryData *>(instance->base_data)->geometry_instance);
2487 }
2488
2489 RSG::mesh_storage->update_mesh_instances();
2490
2491 RSG::light_storage->light_instance_set_shadow_transform(light->instance, cm, light_transform, radius, 0, 0, 0);
2492 shadow_data.light = light->instance;
2493 shadow_data.pass = 0;
2494
2495 } break;
2496 }
2497
2498 return animated_material_found;
2499}
2500
2501void RendererSceneCull::render_camera(const Ref<RenderSceneBuffers> &p_render_buffers, RID p_camera, RID p_scenario, RID p_viewport, Size2 p_viewport_size, bool p_use_taa, float p_screen_mesh_lod_threshold, RID p_shadow_atlas, Ref<XRInterface> &p_xr_interface, RenderInfo *r_render_info) {
2502#ifndef _3D_DISABLED
2503
2504 Camera *camera = camera_owner.get_or_null(p_camera);
2505 ERR_FAIL_COND(!camera);
2506
2507 Vector2 jitter;
2508 if (p_use_taa) {
2509 jitter = taa_jitter_array[RSG::rasterizer->get_frame_number() % TAA_JITTER_COUNT] / p_viewport_size;
2510 }
2511
2512 RendererSceneRender::CameraData camera_data;
2513
2514 // Setup Camera(s)
2515 if (p_xr_interface.is_null()) {
2516 // Normal camera
2517 Transform3D transform = camera->transform;
2518 Projection projection;
2519 bool vaspect = camera->vaspect;
2520 bool is_orthogonal = false;
2521
2522 switch (camera->type) {
2523 case Camera::ORTHOGONAL: {
2524 projection.set_orthogonal(
2525 camera->size,
2526 p_viewport_size.width / (float)p_viewport_size.height,
2527 camera->znear,
2528 camera->zfar,
2529 camera->vaspect);
2530 is_orthogonal = true;
2531 } break;
2532 case Camera::PERSPECTIVE: {
2533 projection.set_perspective(
2534 camera->fov,
2535 p_viewport_size.width / (float)p_viewport_size.height,
2536 camera->znear,
2537 camera->zfar,
2538 camera->vaspect);
2539
2540 } break;
2541 case Camera::FRUSTUM: {
2542 projection.set_frustum(
2543 camera->size,
2544 p_viewport_size.width / (float)p_viewport_size.height,
2545 camera->offset,
2546 camera->znear,
2547 camera->zfar,
2548 camera->vaspect);
2549 } break;
2550 }
2551
2552 camera_data.set_camera(transform, projection, is_orthogonal, vaspect, jitter, camera->visible_layers);
2553 } else {
2554 // Setup our camera for our XR interface.
2555 // We can support multiple views here each with their own camera
2556 Transform3D transforms[RendererSceneRender::MAX_RENDER_VIEWS];
2557 Projection projections[RendererSceneRender::MAX_RENDER_VIEWS];
2558
2559 uint32_t view_count = p_xr_interface->get_view_count();
2560 ERR_FAIL_COND_MSG(view_count == 0 || view_count > RendererSceneRender::MAX_RENDER_VIEWS, "Requested view count is not supported");
2561
2562 float aspect = p_viewport_size.width / (float)p_viewport_size.height;
2563
2564 Transform3D world_origin = XRServer::get_singleton()->get_world_origin();
2565
2566 // We ignore our camera position, it will have been positioned with a slightly old tracking position.
2567 // Instead we take our origin point and have our XR interface add fresh tracking data! Whoohoo!
2568 for (uint32_t v = 0; v < view_count; v++) {
2569 transforms[v] = p_xr_interface->get_transform_for_view(v, world_origin);
2570 projections[v] = p_xr_interface->get_projection_for_view(v, aspect, camera->znear, camera->zfar);
2571 }
2572
2573 if (view_count == 1) {
2574 camera_data.set_camera(transforms[0], projections[0], false, camera->vaspect, jitter, camera->visible_layers);
2575 } else if (view_count == 2) {
2576 camera_data.set_multiview_camera(view_count, transforms, projections, false, camera->vaspect);
2577 } else {
2578 // this won't be called (see fail check above) but keeping this comment to indicate we may support more then 2 views in the future...
2579 }
2580 }
2581
2582 RID environment = _render_get_environment(p_camera, p_scenario);
2583
2584 RENDER_TIMESTAMP("Update Occlusion Buffer")
2585 // For now just cull on the first camera
2586 RendererSceneOcclusionCull::get_singleton()->buffer_update(p_viewport, camera_data.main_transform, camera_data.main_projection, camera_data.is_orthogonal);
2587
2588 _render_scene(&camera_data, p_render_buffers, environment, camera->attributes, camera->visible_layers, p_scenario, p_viewport, p_shadow_atlas, RID(), -1, p_screen_mesh_lod_threshold, true, r_render_info);
2589#endif
2590}
2591
2592void RendererSceneCull::_visibility_cull_threaded(uint32_t p_thread, VisibilityCullData *cull_data) {
2593 uint32_t total_threads = WorkerThreadPool::get_singleton()->get_thread_count();
2594 uint32_t bin_from = p_thread * cull_data->cull_count / total_threads;
2595 uint32_t bin_to = (p_thread + 1 == total_threads) ? cull_data->cull_count : ((p_thread + 1) * cull_data->cull_count / total_threads);
2596
2597 _visibility_cull(*cull_data, cull_data->cull_offset + bin_from, cull_data->cull_offset + bin_to);
2598}
2599
2600void RendererSceneCull::_visibility_cull(const VisibilityCullData &cull_data, uint64_t p_from, uint64_t p_to) {
2601 Scenario *scenario = cull_data.scenario;
2602 for (unsigned int i = p_from; i < p_to; i++) {
2603 InstanceVisibilityData &vd = scenario->instance_visibility[i];
2604 InstanceData &idata = scenario->instance_data[vd.array_index];
2605
2606 if (idata.parent_array_index >= 0) {
2607 uint32_t parent_flags = scenario->instance_data[idata.parent_array_index].flags;
2608
2609 if ((parent_flags & InstanceData::FLAG_VISIBILITY_DEPENDENCY_HIDDEN) || !(parent_flags & (InstanceData::FLAG_VISIBILITY_DEPENDENCY_HIDDEN_CLOSE_RANGE | InstanceData::FLAG_VISIBILITY_DEPENDENCY_FADE_CHILDREN))) {
2610 idata.flags |= InstanceData::FLAG_VISIBILITY_DEPENDENCY_HIDDEN;
2611 idata.flags &= ~InstanceData::FLAG_VISIBILITY_DEPENDENCY_HIDDEN_CLOSE_RANGE;
2612 idata.flags &= ~InstanceData::FLAG_VISIBILITY_DEPENDENCY_FADE_CHILDREN;
2613 continue;
2614 }
2615 }
2616
2617 int range_check = _visibility_range_check<true>(vd, cull_data.camera_position, cull_data.viewport_mask);
2618
2619 if (range_check == -1) {
2620 idata.flags |= InstanceData::FLAG_VISIBILITY_DEPENDENCY_HIDDEN;
2621 idata.flags &= ~InstanceData::FLAG_VISIBILITY_DEPENDENCY_HIDDEN_CLOSE_RANGE;
2622 idata.flags &= ~InstanceData::FLAG_VISIBILITY_DEPENDENCY_FADE_CHILDREN;
2623 } else if (range_check == 1) {
2624 idata.flags &= ~InstanceData::FLAG_VISIBILITY_DEPENDENCY_HIDDEN;
2625 idata.flags |= InstanceData::FLAG_VISIBILITY_DEPENDENCY_HIDDEN_CLOSE_RANGE;
2626 idata.flags &= ~InstanceData::FLAG_VISIBILITY_DEPENDENCY_FADE_CHILDREN;
2627 } else {
2628 idata.flags &= ~InstanceData::FLAG_VISIBILITY_DEPENDENCY_HIDDEN;
2629 idata.flags &= ~InstanceData::FLAG_VISIBILITY_DEPENDENCY_HIDDEN_CLOSE_RANGE;
2630 if (range_check == 2) {
2631 idata.flags |= InstanceData::FLAG_VISIBILITY_DEPENDENCY_FADE_CHILDREN;
2632 } else {
2633 idata.flags &= ~InstanceData::FLAG_VISIBILITY_DEPENDENCY_FADE_CHILDREN;
2634 }
2635 }
2636 }
2637}
2638
2639template <bool p_fade_check>
2640int RendererSceneCull::_visibility_range_check(InstanceVisibilityData &r_vis_data, const Vector3 &p_camera_pos, uint64_t p_viewport_mask) {
2641 float dist = p_camera_pos.distance_to(r_vis_data.position);
2642 const RS::VisibilityRangeFadeMode &fade_mode = r_vis_data.fade_mode;
2643
2644 float begin_offset = -r_vis_data.range_begin_margin;
2645 float end_offset = r_vis_data.range_end_margin;
2646
2647 if (fade_mode == RS::VISIBILITY_RANGE_FADE_DISABLED && !(p_viewport_mask & r_vis_data.viewport_state)) {
2648 begin_offset = -begin_offset;
2649 end_offset = -end_offset;
2650 }
2651
2652 if (r_vis_data.range_end > 0.0f && dist > r_vis_data.range_end + end_offset) {
2653 r_vis_data.viewport_state &= ~p_viewport_mask;
2654 return -1;
2655 } else if (r_vis_data.range_begin > 0.0f && dist < r_vis_data.range_begin + begin_offset) {
2656 r_vis_data.viewport_state &= ~p_viewport_mask;
2657 return 1;
2658 } else {
2659 r_vis_data.viewport_state |= p_viewport_mask;
2660 if (p_fade_check) {
2661 if (fade_mode != RS::VISIBILITY_RANGE_FADE_DISABLED) {
2662 r_vis_data.children_fade_alpha = 1.0f;
2663 if (r_vis_data.range_end > 0.0f && dist > r_vis_data.range_end - end_offset) {
2664 if (fade_mode == RS::VISIBILITY_RANGE_FADE_DEPENDENCIES) {
2665 r_vis_data.children_fade_alpha = MIN(1.0f, (dist - (r_vis_data.range_end - end_offset)) / (2.0f * r_vis_data.range_end_margin));
2666 }
2667 return 2;
2668 } else if (r_vis_data.range_begin > 0.0f && dist < r_vis_data.range_begin - begin_offset) {
2669 if (fade_mode == RS::VISIBILITY_RANGE_FADE_DEPENDENCIES) {
2670 r_vis_data.children_fade_alpha = MIN(1.0f, 1.0 - (dist - (r_vis_data.range_begin + begin_offset)) / (2.0f * r_vis_data.range_begin_margin));
2671 }
2672 return 2;
2673 }
2674 }
2675 }
2676 return 0;
2677 }
2678}
2679
2680bool RendererSceneCull::_visibility_parent_check(const CullData &p_cull_data, const InstanceData &p_instance_data) {
2681 if (p_instance_data.parent_array_index == -1) {
2682 return true;
2683 }
2684 const uint32_t &parent_flags = p_cull_data.scenario->instance_data[p_instance_data.parent_array_index].flags;
2685 return ((parent_flags & InstanceData::FLAG_VISIBILITY_DEPENDENCY_NEEDS_CHECK) == InstanceData::FLAG_VISIBILITY_DEPENDENCY_HIDDEN_CLOSE_RANGE) || (parent_flags & InstanceData::FLAG_VISIBILITY_DEPENDENCY_FADE_CHILDREN);
2686}
2687
2688void RendererSceneCull::_scene_cull_threaded(uint32_t p_thread, CullData *cull_data) {
2689 uint32_t cull_total = cull_data->scenario->instance_data.size();
2690 uint32_t total_threads = WorkerThreadPool::get_singleton()->get_thread_count();
2691 uint32_t cull_from = p_thread * cull_total / total_threads;
2692 uint32_t cull_to = (p_thread + 1 == total_threads) ? cull_total : ((p_thread + 1) * cull_total / total_threads);
2693
2694 _scene_cull(*cull_data, scene_cull_result_threads[p_thread], cull_from, cull_to);
2695}
2696
2697void RendererSceneCull::_scene_cull(CullData &cull_data, InstanceCullResult &cull_result, uint64_t p_from, uint64_t p_to) {
2698 uint64_t frame_number = RSG::rasterizer->get_frame_number();
2699 float lightmap_probe_update_speed = RSG::light_storage->lightmap_get_probe_capture_update_speed() * RSG::rasterizer->get_frame_delta_time();
2700
2701 uint32_t sdfgi_last_light_index = 0xFFFFFFFF;
2702 uint32_t sdfgi_last_light_cascade = 0xFFFFFFFF;
2703
2704 RID instance_pair_buffer[MAX_INSTANCE_PAIRS];
2705
2706 Transform3D inv_cam_transform = cull_data.cam_transform.inverse();
2707 float z_near = cull_data.camera_matrix->get_z_near();
2708
2709 for (uint64_t i = p_from; i < p_to; i++) {
2710 bool mesh_visible = false;
2711
2712 InstanceData &idata = cull_data.scenario->instance_data[i];
2713 uint32_t visibility_flags = idata.flags & (InstanceData::FLAG_VISIBILITY_DEPENDENCY_HIDDEN_CLOSE_RANGE | InstanceData::FLAG_VISIBILITY_DEPENDENCY_HIDDEN | InstanceData::FLAG_VISIBILITY_DEPENDENCY_FADE_CHILDREN);
2714 int32_t visibility_check = -1;
2715
2716#define HIDDEN_BY_VISIBILITY_CHECKS (visibility_flags == InstanceData::FLAG_VISIBILITY_DEPENDENCY_HIDDEN_CLOSE_RANGE || visibility_flags == InstanceData::FLAG_VISIBILITY_DEPENDENCY_HIDDEN)
2717#define LAYER_CHECK (cull_data.visible_layers & idata.layer_mask)
2718#define IN_FRUSTUM(f) (cull_data.scenario->instance_aabbs[i].in_frustum(f))
2719#define VIS_RANGE_CHECK ((idata.visibility_index == -1) || _visibility_range_check<false>(cull_data.scenario->instance_visibility[idata.visibility_index], cull_data.cam_transform.origin, cull_data.visibility_viewport_mask) == 0)
2720#define VIS_PARENT_CHECK (_visibility_parent_check(cull_data, idata))
2721#define VIS_CHECK (visibility_check < 0 ? (visibility_check = (visibility_flags != InstanceData::FLAG_VISIBILITY_DEPENDENCY_NEEDS_CHECK || (VIS_RANGE_CHECK && VIS_PARENT_CHECK))) : visibility_check)
2722#define OCCLUSION_CULLED (cull_data.occlusion_buffer != nullptr && (cull_data.scenario->instance_data[i].flags & InstanceData::FLAG_IGNORE_OCCLUSION_CULLING) == 0 && cull_data.occlusion_buffer->is_occluded(cull_data.scenario->instance_aabbs[i].bounds, cull_data.cam_transform.origin, inv_cam_transform, *cull_data.camera_matrix, z_near))
2723
2724 if (!HIDDEN_BY_VISIBILITY_CHECKS) {
2725 if ((LAYER_CHECK && IN_FRUSTUM(cull_data.cull->frustum) && VIS_CHECK && !OCCLUSION_CULLED) || (cull_data.scenario->instance_data[i].flags & InstanceData::FLAG_IGNORE_ALL_CULLING)) {
2726 uint32_t base_type = idata.flags & InstanceData::FLAG_BASE_TYPE_MASK;
2727 if (base_type == RS::INSTANCE_LIGHT) {
2728 cull_result.lights.push_back(idata.instance);
2729 cull_result.light_instances.push_back(RID::from_uint64(idata.instance_data_rid));
2730 if (cull_data.shadow_atlas.is_valid() && RSG::light_storage->light_has_shadow(idata.base_rid)) {
2731 RSG::light_storage->light_instance_mark_visible(RID::from_uint64(idata.instance_data_rid)); //mark it visible for shadow allocation later
2732 }
2733
2734 } else if (base_type == RS::INSTANCE_REFLECTION_PROBE) {
2735 if (cull_data.render_reflection_probe != idata.instance) {
2736 //avoid entering The Matrix
2737
2738 if ((idata.flags & InstanceData::FLAG_REFLECTION_PROBE_DIRTY) || RSG::light_storage->reflection_probe_instance_needs_redraw(RID::from_uint64(idata.instance_data_rid))) {
2739 InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(idata.instance->base_data);
2740 cull_data.cull->lock.lock();
2741 if (!reflection_probe->update_list.in_list()) {
2742 reflection_probe->render_step = 0;
2743 reflection_probe_render_list.add_last(&reflection_probe->update_list);
2744 }
2745 cull_data.cull->lock.unlock();
2746
2747 idata.flags &= ~uint32_t(InstanceData::FLAG_REFLECTION_PROBE_DIRTY);
2748 }
2749
2750 if (RSG::light_storage->reflection_probe_instance_has_reflection(RID::from_uint64(idata.instance_data_rid))) {
2751 cull_result.reflections.push_back(RID::from_uint64(idata.instance_data_rid));
2752 }
2753 }
2754 } else if (base_type == RS::INSTANCE_DECAL) {
2755 cull_result.decals.push_back(RID::from_uint64(idata.instance_data_rid));
2756
2757 } else if (base_type == RS::INSTANCE_VOXEL_GI) {
2758 InstanceVoxelGIData *voxel_gi = static_cast<InstanceVoxelGIData *>(idata.instance->base_data);
2759 cull_data.cull->lock.lock();
2760 if (!voxel_gi->update_element.in_list()) {
2761 voxel_gi_update_list.add(&voxel_gi->update_element);
2762 }
2763 cull_data.cull->lock.unlock();
2764 cull_result.voxel_gi_instances.push_back(RID::from_uint64(idata.instance_data_rid));
2765
2766 } else if (base_type == RS::INSTANCE_LIGHTMAP) {
2767 cull_result.lightmaps.push_back(RID::from_uint64(idata.instance_data_rid));
2768 } else if (base_type == RS::INSTANCE_FOG_VOLUME) {
2769 cull_result.fog_volumes.push_back(RID::from_uint64(idata.instance_data_rid));
2770 } else if (base_type == RS::INSTANCE_VISIBLITY_NOTIFIER) {
2771 InstanceVisibilityNotifierData *vnd = idata.visibility_notifier;
2772 if (!vnd->list_element.in_list()) {
2773 visible_notifier_list_lock.lock();
2774 visible_notifier_list.add(&vnd->list_element);
2775 visible_notifier_list_lock.unlock();
2776 vnd->just_visible = true;
2777 }
2778 vnd->visible_in_frame = RSG::rasterizer->get_frame_number();
2779 } else if (((1 << base_type) & RS::INSTANCE_GEOMETRY_MASK) && !(idata.flags & InstanceData::FLAG_CAST_SHADOWS_ONLY)) {
2780 bool keep = true;
2781
2782 if (idata.flags & InstanceData::FLAG_REDRAW_IF_VISIBLE) {
2783 RenderingServerDefault::redraw_request();
2784 }
2785
2786 if (base_type == RS::INSTANCE_MESH) {
2787 mesh_visible = true;
2788 } else if (base_type == RS::INSTANCE_PARTICLES) {
2789 //particles visible? process them
2790 if (RSG::particles_storage->particles_is_inactive(idata.base_rid)) {
2791 //but if nothing is going on, don't do it.
2792 keep = false;
2793 } else {
2794 cull_data.cull->lock.lock();
2795 RSG::particles_storage->particles_request_process(idata.base_rid);
2796 cull_data.cull->lock.unlock();
2797 RSG::particles_storage->particles_set_view_axis(idata.base_rid, -cull_data.cam_transform.basis.get_column(2).normalized(), cull_data.cam_transform.basis.get_column(1).normalized());
2798 //particles visible? request redraw
2799 RenderingServerDefault::redraw_request();
2800 }
2801 }
2802
2803 if (idata.parent_array_index != -1) {
2804 float fade = 1.0f;
2805 const uint32_t &parent_flags = cull_data.scenario->instance_data[idata.parent_array_index].flags;
2806 if (parent_flags & InstanceData::FLAG_VISIBILITY_DEPENDENCY_FADE_CHILDREN) {
2807 const int32_t &parent_idx = cull_data.scenario->instance_data[idata.parent_array_index].visibility_index;
2808 fade = cull_data.scenario->instance_visibility[parent_idx].children_fade_alpha;
2809 }
2810 idata.instance_geometry->set_parent_fade_alpha(fade);
2811 }
2812
2813 if (geometry_instance_pair_mask & (1 << RS::INSTANCE_LIGHT) && (idata.flags & InstanceData::FLAG_GEOM_LIGHTING_DIRTY)) {
2814 InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(idata.instance->base_data);
2815 uint32_t idx = 0;
2816
2817 for (const Instance *E : geom->lights) {
2818 InstanceLightData *light = static_cast<InstanceLightData *>(E->base_data);
2819 instance_pair_buffer[idx++] = light->instance;
2820 if (idx == MAX_INSTANCE_PAIRS) {
2821 break;
2822 }
2823 }
2824
2825 ERR_FAIL_NULL(geom->geometry_instance);
2826 geom->geometry_instance->pair_light_instances(instance_pair_buffer, idx);
2827 idata.flags &= ~uint32_t(InstanceData::FLAG_GEOM_LIGHTING_DIRTY);
2828 }
2829
2830 if (idata.flags & InstanceData::FLAG_GEOM_PROJECTOR_SOFTSHADOW_DIRTY) {
2831 InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(idata.instance->base_data);
2832
2833 ERR_FAIL_NULL(geom->geometry_instance);
2834 cull_data.cull->lock.lock();
2835 geom->geometry_instance->set_softshadow_projector_pairing(geom->softshadow_count > 0, geom->projector_count > 0);
2836 cull_data.cull->lock.unlock();
2837 idata.flags &= ~uint32_t(InstanceData::FLAG_GEOM_PROJECTOR_SOFTSHADOW_DIRTY);
2838 }
2839
2840 if (geometry_instance_pair_mask & (1 << RS::INSTANCE_REFLECTION_PROBE) && (idata.flags & InstanceData::FLAG_GEOM_REFLECTION_DIRTY)) {
2841 InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(idata.instance->base_data);
2842 uint32_t idx = 0;
2843
2844 for (const Instance *E : geom->reflection_probes) {
2845 InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(E->base_data);
2846
2847 instance_pair_buffer[idx++] = reflection_probe->instance;
2848 if (idx == MAX_INSTANCE_PAIRS) {
2849 break;
2850 }
2851 }
2852
2853 ERR_FAIL_NULL(geom->geometry_instance);
2854 geom->geometry_instance->pair_reflection_probe_instances(instance_pair_buffer, idx);
2855 idata.flags &= ~uint32_t(InstanceData::FLAG_GEOM_REFLECTION_DIRTY);
2856 }
2857
2858 if (geometry_instance_pair_mask & (1 << RS::INSTANCE_DECAL) && (idata.flags & InstanceData::FLAG_GEOM_DECAL_DIRTY)) {
2859 InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(idata.instance->base_data);
2860 uint32_t idx = 0;
2861
2862 for (const Instance *E : geom->decals) {
2863 InstanceDecalData *decal = static_cast<InstanceDecalData *>(E->base_data);
2864
2865 instance_pair_buffer[idx++] = decal->instance;
2866 if (idx == MAX_INSTANCE_PAIRS) {
2867 break;
2868 }
2869 }
2870
2871 ERR_FAIL_NULL(geom->geometry_instance);
2872 geom->geometry_instance->pair_decal_instances(instance_pair_buffer, idx);
2873
2874 idata.flags &= ~uint32_t(InstanceData::FLAG_GEOM_DECAL_DIRTY);
2875 }
2876
2877 if (idata.flags & InstanceData::FLAG_GEOM_VOXEL_GI_DIRTY) {
2878 InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(idata.instance->base_data);
2879 uint32_t idx = 0;
2880 for (const Instance *E : geom->voxel_gi_instances) {
2881 InstanceVoxelGIData *voxel_gi = static_cast<InstanceVoxelGIData *>(E->base_data);
2882
2883 instance_pair_buffer[idx++] = voxel_gi->probe_instance;
2884 if (idx == MAX_INSTANCE_PAIRS) {
2885 break;
2886 }
2887 }
2888
2889 ERR_FAIL_NULL(geom->geometry_instance);
2890 geom->geometry_instance->pair_voxel_gi_instances(instance_pair_buffer, idx);
2891
2892 idata.flags &= ~uint32_t(InstanceData::FLAG_GEOM_VOXEL_GI_DIRTY);
2893 }
2894
2895 if ((idata.flags & InstanceData::FLAG_LIGHTMAP_CAPTURE) && idata.instance->last_frame_pass != frame_number && !idata.instance->lightmap_target_sh.is_empty() && !idata.instance->lightmap_sh.is_empty()) {
2896 InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(idata.instance->base_data);
2897 Color *sh = idata.instance->lightmap_sh.ptrw();
2898 const Color *target_sh = idata.instance->lightmap_target_sh.ptr();
2899 for (uint32_t j = 0; j < 9; j++) {
2900 sh[j] = sh[j].lerp(target_sh[j], MIN(1.0, lightmap_probe_update_speed));
2901 }
2902 ERR_FAIL_NULL(geom->geometry_instance);
2903 cull_data.cull->lock.lock();
2904 geom->geometry_instance->set_lightmap_capture(sh);
2905 cull_data.cull->lock.unlock();
2906 idata.instance->last_frame_pass = frame_number;
2907 }
2908
2909 if (keep) {
2910 cull_result.geometry_instances.push_back(idata.instance_geometry);
2911 }
2912 }
2913 }
2914
2915 for (uint32_t j = 0; j < cull_data.cull->shadow_count; j++) {
2916 for (uint32_t k = 0; k < cull_data.cull->shadows[j].cascade_count; k++) {
2917 if (IN_FRUSTUM(cull_data.cull->shadows[j].cascades[k].frustum) && VIS_CHECK) {
2918 uint32_t base_type = idata.flags & InstanceData::FLAG_BASE_TYPE_MASK;
2919
2920 if (((1 << base_type) & RS::INSTANCE_GEOMETRY_MASK) && idata.flags & InstanceData::FLAG_CAST_SHADOWS && LAYER_CHECK) {
2921 cull_result.directional_shadows[j].cascade_geometry_instances[k].push_back(idata.instance_geometry);
2922 mesh_visible = true;
2923 }
2924 }
2925 }
2926 }
2927 }
2928
2929#undef HIDDEN_BY_VISIBILITY_CHECKS
2930#undef LAYER_CHECK
2931#undef IN_FRUSTUM
2932#undef VIS_RANGE_CHECK
2933#undef VIS_PARENT_CHECK
2934#undef VIS_CHECK
2935#undef OCCLUSION_CULLED
2936
2937 for (uint32_t j = 0; j < cull_data.cull->sdfgi.region_count; j++) {
2938 if (cull_data.scenario->instance_aabbs[i].in_aabb(cull_data.cull->sdfgi.region_aabb[j])) {
2939 uint32_t base_type = idata.flags & InstanceData::FLAG_BASE_TYPE_MASK;
2940
2941 if (base_type == RS::INSTANCE_LIGHT) {
2942 InstanceLightData *instance_light = (InstanceLightData *)idata.instance->base_data;
2943 if (instance_light->bake_mode == RS::LIGHT_BAKE_STATIC && cull_data.cull->sdfgi.region_cascade[j] <= instance_light->max_sdfgi_cascade) {
2944 if (sdfgi_last_light_index != i || sdfgi_last_light_cascade != cull_data.cull->sdfgi.region_cascade[j]) {
2945 sdfgi_last_light_index = i;
2946 sdfgi_last_light_cascade = cull_data.cull->sdfgi.region_cascade[j];
2947 cull_result.sdfgi_cascade_lights[sdfgi_last_light_cascade].push_back(instance_light->instance);
2948 }
2949 }
2950 } else if ((1 << base_type) & RS::INSTANCE_GEOMETRY_MASK) {
2951 if (idata.flags & InstanceData::FLAG_USES_BAKED_LIGHT) {
2952 cull_result.sdfgi_region_geometry_instances[j].push_back(idata.instance_geometry);
2953 mesh_visible = true;
2954 }
2955 }
2956 }
2957 }
2958
2959 if (mesh_visible && cull_data.scenario->instance_data[i].flags & InstanceData::FLAG_USES_MESH_INSTANCE) {
2960 cull_result.mesh_instances.push_back(cull_data.scenario->instance_data[i].instance->mesh_instance);
2961 }
2962 }
2963}
2964
2965void RendererSceneCull::_render_scene(const RendererSceneRender::CameraData *p_camera_data, const Ref<RenderSceneBuffers> &p_render_buffers, RID p_environment, RID p_force_camera_attributes, uint32_t p_visible_layers, RID p_scenario, RID p_viewport, RID p_shadow_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, bool p_using_shadows, RenderingMethod::RenderInfo *r_render_info) {
2966 Instance *render_reflection_probe = instance_owner.get_or_null(p_reflection_probe); //if null, not rendering to it
2967
2968 Scenario *scenario = scenario_owner.get_or_null(p_scenario);
2969
2970 ERR_FAIL_COND(p_render_buffers.is_null());
2971
2972 render_pass++;
2973
2974 scene_render->set_scene_pass(render_pass);
2975
2976 if (p_reflection_probe.is_null()) {
2977 //no rendering code here, this is only to set up what needs to be done, request regions, etc.
2978 scene_render->sdfgi_update(p_render_buffers, p_environment, p_camera_data->main_transform.origin); //update conditions for SDFGI (whether its used or not)
2979 }
2980
2981 RENDER_TIMESTAMP("Update Visibility Dependencies");
2982
2983 if (scenario->instance_visibility.get_bin_count() > 0) {
2984 if (!scenario->viewport_visibility_masks.has(p_viewport)) {
2985 scenario_add_viewport_visibility_mask(scenario->self, p_viewport);
2986 }
2987
2988 VisibilityCullData visibility_cull_data;
2989 visibility_cull_data.scenario = scenario;
2990 visibility_cull_data.viewport_mask = scenario->viewport_visibility_masks[p_viewport];
2991 visibility_cull_data.camera_position = p_camera_data->main_transform.origin;
2992
2993 for (int i = scenario->instance_visibility.get_bin_count() - 1; i > 0; i--) { // We skip bin 0
2994 visibility_cull_data.cull_offset = scenario->instance_visibility.get_bin_start(i);
2995 visibility_cull_data.cull_count = scenario->instance_visibility.get_bin_size(i);
2996
2997 if (visibility_cull_data.cull_count == 0) {
2998 continue;
2999 }
3000
3001 if (visibility_cull_data.cull_count > thread_cull_threshold) {
3002 WorkerThreadPool::GroupID group_task = WorkerThreadPool::get_singleton()->add_template_group_task(this, &RendererSceneCull::_visibility_cull_threaded, &visibility_cull_data, WorkerThreadPool::get_singleton()->get_thread_count(), -1, true, SNAME("VisibilityCullInstances"));
3003 WorkerThreadPool::get_singleton()->wait_for_group_task_completion(group_task);
3004 } else {
3005 _visibility_cull(visibility_cull_data, visibility_cull_data.cull_offset, visibility_cull_data.cull_offset + visibility_cull_data.cull_count);
3006 }
3007 }
3008 }
3009
3010 RENDER_TIMESTAMP("Cull 3D Scene");
3011
3012 //rasterizer->set_camera(p_camera_data->main_transform, p_camera_data.main_projection, p_camera_data.is_orthogonal);
3013
3014 /* STEP 2 - CULL */
3015
3016 Vector<Plane> planes = p_camera_data->main_projection.get_projection_planes(p_camera_data->main_transform);
3017 cull.frustum = Frustum(planes);
3018
3019 Vector<RID> directional_lights;
3020 // directional lights
3021 {
3022 cull.shadow_count = 0;
3023
3024 Vector<Instance *> lights_with_shadow;
3025
3026 for (Instance *E : scenario->directional_lights) {
3027 if (!E->visible) {
3028 continue;
3029 }
3030
3031 if (directional_lights.size() > RendererSceneRender::MAX_DIRECTIONAL_LIGHTS) {
3032 break;
3033 }
3034
3035 InstanceLightData *light = static_cast<InstanceLightData *>(E->base_data);
3036
3037 //check shadow..
3038
3039 if (light) {
3040 if (p_using_shadows && p_shadow_atlas.is_valid() && RSG::light_storage->light_has_shadow(E->base) && !(RSG::light_storage->light_get_type(E->base) == RS::LIGHT_DIRECTIONAL && RSG::light_storage->light_directional_get_sky_mode(E->base) == RS::LIGHT_DIRECTIONAL_SKY_MODE_SKY_ONLY)) {
3041 lights_with_shadow.push_back(E);
3042 }
3043 //add to list
3044 directional_lights.push_back(light->instance);
3045 }
3046 }
3047
3048 RSG::light_storage->set_directional_shadow_count(lights_with_shadow.size());
3049
3050 for (int i = 0; i < lights_with_shadow.size(); i++) {
3051 _light_instance_setup_directional_shadow(i, lights_with_shadow[i], p_camera_data->main_transform, p_camera_data->main_projection, p_camera_data->is_orthogonal, p_camera_data->vaspect);
3052 }
3053 }
3054
3055 { //sdfgi
3056 cull.sdfgi.region_count = 0;
3057
3058 if (p_reflection_probe.is_null()) {
3059 cull.sdfgi.cascade_light_count = 0;
3060
3061 uint32_t prev_cascade = 0xFFFFFFFF;
3062 uint32_t pending_region_count = scene_render->sdfgi_get_pending_region_count(p_render_buffers);
3063
3064 for (uint32_t i = 0; i < pending_region_count; i++) {
3065 cull.sdfgi.region_aabb[i] = scene_render->sdfgi_get_pending_region_bounds(p_render_buffers, i);
3066 uint32_t region_cascade = scene_render->sdfgi_get_pending_region_cascade(p_render_buffers, i);
3067 cull.sdfgi.region_cascade[i] = region_cascade;
3068
3069 if (region_cascade != prev_cascade) {
3070 cull.sdfgi.cascade_light_index[cull.sdfgi.cascade_light_count] = region_cascade;
3071 cull.sdfgi.cascade_light_count++;
3072 prev_cascade = region_cascade;
3073 }
3074 }
3075
3076 cull.sdfgi.region_count = pending_region_count;
3077 }
3078 }
3079
3080 scene_cull_result.clear();
3081
3082 {
3083 uint64_t cull_from = 0;
3084 uint64_t cull_to = scenario->instance_data.size();
3085
3086 CullData cull_data;
3087
3088 //prepare for eventual thread usage
3089 cull_data.cull = &cull;
3090 cull_data.scenario = scenario;
3091 cull_data.shadow_atlas = p_shadow_atlas;
3092 cull_data.cam_transform = p_camera_data->main_transform;
3093 cull_data.visible_layers = p_visible_layers;
3094 cull_data.render_reflection_probe = render_reflection_probe;
3095 cull_data.occlusion_buffer = RendererSceneOcclusionCull::get_singleton()->buffer_get_ptr(p_viewport);
3096 cull_data.camera_matrix = &p_camera_data->main_projection;
3097 cull_data.visibility_viewport_mask = scenario->viewport_visibility_masks.has(p_viewport) ? scenario->viewport_visibility_masks[p_viewport] : 0;
3098//#define DEBUG_CULL_TIME
3099#ifdef DEBUG_CULL_TIME
3100 uint64_t time_from = OS::get_singleton()->get_ticks_usec();
3101#endif
3102 if (cull_to > thread_cull_threshold) {
3103 //multiple threads
3104 for (InstanceCullResult &thread : scene_cull_result_threads) {
3105 thread.clear();
3106 }
3107
3108 WorkerThreadPool::GroupID group_task = WorkerThreadPool::get_singleton()->add_template_group_task(this, &RendererSceneCull::_scene_cull_threaded, &cull_data, scene_cull_result_threads.size(), -1, true, SNAME("RenderCullInstances"));
3109 WorkerThreadPool::get_singleton()->wait_for_group_task_completion(group_task);
3110
3111 for (InstanceCullResult &thread : scene_cull_result_threads) {
3112 scene_cull_result.append_from(thread);
3113 }
3114
3115 } else {
3116 //single threaded
3117 _scene_cull(cull_data, scene_cull_result, cull_from, cull_to);
3118 }
3119
3120#ifdef DEBUG_CULL_TIME
3121 static float time_avg = 0;
3122 static uint32_t time_count = 0;
3123 time_avg += double(OS::get_singleton()->get_ticks_usec() - time_from) / 1000.0;
3124 time_count++;
3125 print_line("time taken: " + rtos(time_avg / time_count));
3126#endif
3127
3128 if (scene_cull_result.mesh_instances.size()) {
3129 for (uint64_t i = 0; i < scene_cull_result.mesh_instances.size(); i++) {
3130 RSG::mesh_storage->mesh_instance_check_for_update(scene_cull_result.mesh_instances[i]);
3131 }
3132 RSG::mesh_storage->update_mesh_instances();
3133 }
3134 }
3135
3136 //render shadows
3137
3138 max_shadows_used = 0;
3139
3140 if (p_using_shadows) { //setup shadow maps
3141
3142 // Directional Shadows
3143
3144 for (uint32_t i = 0; i < cull.shadow_count; i++) {
3145 for (uint32_t j = 0; j < cull.shadows[i].cascade_count; j++) {
3146 const Cull::Shadow::Cascade &c = cull.shadows[i].cascades[j];
3147 // print_line("shadow " + itos(i) + " cascade " + itos(j) + " elements: " + itos(c.cull_result.size()));
3148 RSG::light_storage->light_instance_set_shadow_transform(cull.shadows[i].light_instance, c.projection, c.transform, c.zfar, c.split, j, c.shadow_texel_size, c.bias_scale, c.range_begin, c.uv_scale);
3149 if (max_shadows_used == MAX_UPDATE_SHADOWS) {
3150 continue;
3151 }
3152 render_shadow_data[max_shadows_used].light = cull.shadows[i].light_instance;
3153 render_shadow_data[max_shadows_used].pass = j;
3154 render_shadow_data[max_shadows_used].instances.merge_unordered(scene_cull_result.directional_shadows[i].cascade_geometry_instances[j]);
3155 max_shadows_used++;
3156 }
3157 }
3158
3159 // Positional Shadowss
3160 for (uint32_t i = 0; i < (uint32_t)scene_cull_result.lights.size(); i++) {
3161 Instance *ins = scene_cull_result.lights[i];
3162
3163 if (!p_shadow_atlas.is_valid() || !RSG::light_storage->light_has_shadow(ins->base)) {
3164 continue;
3165 }
3166
3167 InstanceLightData *light = static_cast<InstanceLightData *>(ins->base_data);
3168
3169 float coverage = 0.f;
3170
3171 { //compute coverage
3172
3173 Transform3D cam_xf = p_camera_data->main_transform;
3174 float zn = p_camera_data->main_projection.get_z_near();
3175 Plane p(-cam_xf.basis.get_column(2), cam_xf.origin + cam_xf.basis.get_column(2) * -zn); //camera near plane
3176
3177 // near plane half width and height
3178 Vector2 vp_half_extents = p_camera_data->main_projection.get_viewport_half_extents();
3179
3180 switch (RSG::light_storage->light_get_type(ins->base)) {
3181 case RS::LIGHT_OMNI: {
3182 float radius = RSG::light_storage->light_get_param(ins->base, RS::LIGHT_PARAM_RANGE);
3183
3184 //get two points parallel to near plane
3185 Vector3 points[2] = {
3186 ins->transform.origin,
3187 ins->transform.origin + cam_xf.basis.get_column(0) * radius
3188 };
3189
3190 if (!p_camera_data->is_orthogonal) {
3191 //if using perspetive, map them to near plane
3192 for (int j = 0; j < 2; j++) {
3193 if (p.distance_to(points[j]) < 0) {
3194 points[j].z = -zn; //small hack to keep size constant when hitting the screen
3195 }
3196
3197 p.intersects_segment(cam_xf.origin, points[j], &points[j]); //map to plane
3198 }
3199 }
3200
3201 float screen_diameter = points[0].distance_to(points[1]) * 2;
3202 coverage = screen_diameter / (vp_half_extents.x + vp_half_extents.y);
3203 } break;
3204 case RS::LIGHT_SPOT: {
3205 float radius = RSG::light_storage->light_get_param(ins->base, RS::LIGHT_PARAM_RANGE);
3206 float angle = RSG::light_storage->light_get_param(ins->base, RS::LIGHT_PARAM_SPOT_ANGLE);
3207
3208 float w = radius * Math::sin(Math::deg_to_rad(angle));
3209 float d = radius * Math::cos(Math::deg_to_rad(angle));
3210
3211 Vector3 base = ins->transform.origin - ins->transform.basis.get_column(2).normalized() * d;
3212
3213 Vector3 points[2] = {
3214 base,
3215 base + cam_xf.basis.get_column(0) * w
3216 };
3217
3218 if (!p_camera_data->is_orthogonal) {
3219 //if using perspetive, map them to near plane
3220 for (int j = 0; j < 2; j++) {
3221 if (p.distance_to(points[j]) < 0) {
3222 points[j].z = -zn; //small hack to keep size constant when hitting the screen
3223 }
3224
3225 p.intersects_segment(cam_xf.origin, points[j], &points[j]); //map to plane
3226 }
3227 }
3228
3229 float screen_diameter = points[0].distance_to(points[1]) * 2;
3230 coverage = screen_diameter / (vp_half_extents.x + vp_half_extents.y);
3231
3232 } break;
3233 default: {
3234 ERR_PRINT("Invalid Light Type");
3235 }
3236 }
3237 }
3238
3239 if (light->shadow_dirty) {
3240 light->last_version++;
3241 light->shadow_dirty = false;
3242 }
3243
3244 bool redraw = RSG::light_storage->shadow_atlas_update_light(p_shadow_atlas, light->instance, coverage, light->last_version);
3245
3246 if (redraw && max_shadows_used < MAX_UPDATE_SHADOWS) {
3247 //must redraw!
3248 RENDER_TIMESTAMP("> Render Light3D " + itos(i));
3249 light->shadow_dirty = _light_instance_update_shadow(ins, p_camera_data->main_transform, p_camera_data->main_projection, p_camera_data->is_orthogonal, p_camera_data->vaspect, p_shadow_atlas, scenario, p_screen_mesh_lod_threshold, p_visible_layers);
3250 RENDER_TIMESTAMP("< Render Light3D " + itos(i));
3251 } else {
3252 light->shadow_dirty = redraw;
3253 }
3254 }
3255 }
3256
3257 //render SDFGI
3258
3259 {
3260 // Q: Should this whole block be skipped if we're rendering our reflection probe?
3261
3262 sdfgi_update_data.update_static = false;
3263
3264 if (cull.sdfgi.region_count > 0) {
3265 //update regions
3266 for (uint32_t i = 0; i < cull.sdfgi.region_count; i++) {
3267 render_sdfgi_data[i].instances.merge_unordered(scene_cull_result.sdfgi_region_geometry_instances[i]);
3268 render_sdfgi_data[i].region = i;
3269 }
3270 //check if static lights were culled
3271 bool static_lights_culled = false;
3272 for (uint32_t i = 0; i < cull.sdfgi.cascade_light_count; i++) {
3273 if (scene_cull_result.sdfgi_cascade_lights[i].size()) {
3274 static_lights_culled = true;
3275 break;
3276 }
3277 }
3278
3279 if (static_lights_culled) {
3280 sdfgi_update_data.static_cascade_count = cull.sdfgi.cascade_light_count;
3281 sdfgi_update_data.static_cascade_indices = cull.sdfgi.cascade_light_index;
3282 sdfgi_update_data.static_positional_lights = scene_cull_result.sdfgi_cascade_lights;
3283 sdfgi_update_data.update_static = true;
3284 }
3285 }
3286
3287 if (p_reflection_probe.is_null()) {
3288 sdfgi_update_data.directional_lights = &directional_lights;
3289 sdfgi_update_data.positional_light_instances = scenario->dynamic_lights.ptr();
3290 sdfgi_update_data.positional_light_count = scenario->dynamic_lights.size();
3291 }
3292 }
3293
3294 //append the directional lights to the lights culled
3295 for (int i = 0; i < directional_lights.size(); i++) {
3296 scene_cull_result.light_instances.push_back(directional_lights[i]);
3297 }
3298
3299 RID camera_attributes;
3300 if (p_force_camera_attributes.is_valid()) {
3301 camera_attributes = p_force_camera_attributes;
3302 } else {
3303 camera_attributes = scenario->camera_attributes;
3304 }
3305 /* PROCESS GEOMETRY AND DRAW SCENE */
3306
3307 RID occluders_tex;
3308 const RendererSceneRender::CameraData *prev_camera_data = p_camera_data;
3309 if (p_viewport.is_valid()) {
3310 occluders_tex = RSG::viewport->viewport_get_occluder_debug_texture(p_viewport);
3311 prev_camera_data = RSG::viewport->viewport_get_prev_camera_data(p_viewport);
3312 }
3313
3314 RENDER_TIMESTAMP("Render 3D Scene");
3315 scene_render->render_scene(p_render_buffers, p_camera_data, prev_camera_data, scene_cull_result.geometry_instances, scene_cull_result.light_instances, scene_cull_result.reflections, scene_cull_result.voxel_gi_instances, scene_cull_result.decals, scene_cull_result.lightmaps, scene_cull_result.fog_volumes, p_environment, camera_attributes, p_shadow_atlas, occluders_tex, p_reflection_probe.is_valid() ? RID() : scenario->reflection_atlas, p_reflection_probe, p_reflection_probe_pass, p_screen_mesh_lod_threshold, render_shadow_data, max_shadows_used, render_sdfgi_data, cull.sdfgi.region_count, &sdfgi_update_data, r_render_info);
3316
3317 if (p_viewport.is_valid()) {
3318 RSG::viewport->viewport_set_prev_camera_data(p_viewport, p_camera_data);
3319 }
3320
3321 for (uint32_t i = 0; i < max_shadows_used; i++) {
3322 render_shadow_data[i].instances.clear();
3323 }
3324 max_shadows_used = 0;
3325
3326 for (uint32_t i = 0; i < cull.sdfgi.region_count; i++) {
3327 render_sdfgi_data[i].instances.clear();
3328 }
3329}
3330
3331RID RendererSceneCull::_render_get_environment(RID p_camera, RID p_scenario) {
3332 Camera *camera = camera_owner.get_or_null(p_camera);
3333 if (camera && scene_render->is_environment(camera->env)) {
3334 return camera->env;
3335 }
3336
3337 Scenario *scenario = scenario_owner.get_or_null(p_scenario);
3338 if (!scenario) {
3339 return RID();
3340 }
3341 if (scene_render->is_environment(scenario->environment)) {
3342 return scenario->environment;
3343 }
3344
3345 if (scene_render->is_environment(scenario->fallback_environment)) {
3346 return scenario->fallback_environment;
3347 }
3348
3349 return RID();
3350}
3351
3352void RendererSceneCull::render_empty_scene(const Ref<RenderSceneBuffers> &p_render_buffers, RID p_scenario, RID p_shadow_atlas) {
3353#ifndef _3D_DISABLED
3354 Scenario *scenario = scenario_owner.get_or_null(p_scenario);
3355
3356 RID environment;
3357 if (scenario->environment.is_valid()) {
3358 environment = scenario->environment;
3359 } else {
3360 environment = scenario->fallback_environment;
3361 }
3362 RENDER_TIMESTAMP("Render Empty 3D Scene");
3363
3364 RendererSceneRender::CameraData camera_data;
3365 camera_data.set_camera(Transform3D(), Projection(), true, false);
3366
3367 scene_render->render_scene(p_render_buffers, &camera_data, &camera_data, PagedArray<RenderGeometryInstance *>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), environment, RID(), p_shadow_atlas, RID(), scenario->reflection_atlas, RID(), 0, 0, nullptr, 0, nullptr, 0, nullptr);
3368#endif
3369}
3370
3371bool RendererSceneCull::_render_reflection_probe_step(Instance *p_instance, int p_step) {
3372 InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(p_instance->base_data);
3373 Scenario *scenario = p_instance->scenario;
3374 ERR_FAIL_COND_V(!scenario, true);
3375
3376 RenderingServerDefault::redraw_request(); //update, so it updates in editor
3377
3378 if (p_step == 0) {
3379 if (!RSG::light_storage->reflection_probe_instance_begin_render(reflection_probe->instance, scenario->reflection_atlas)) {
3380 return true; //all full
3381 }
3382 }
3383
3384 if (p_step >= 0 && p_step < 6) {
3385 static const Vector3 view_normals[6] = {
3386 Vector3(+1, 0, 0),
3387 Vector3(-1, 0, 0),
3388 Vector3(0, +1, 0),
3389 Vector3(0, -1, 0),
3390 Vector3(0, 0, +1),
3391 Vector3(0, 0, -1)
3392 };
3393 static const Vector3 view_up[6] = {
3394 Vector3(0, -1, 0),
3395 Vector3(0, -1, 0),
3396 Vector3(0, 0, +1),
3397 Vector3(0, 0, -1),
3398 Vector3(0, -1, 0),
3399 Vector3(0, -1, 0)
3400 };
3401
3402 Vector3 probe_size = RSG::light_storage->reflection_probe_get_size(p_instance->base);
3403 Vector3 origin_offset = RSG::light_storage->reflection_probe_get_origin_offset(p_instance->base);
3404 float max_distance = RSG::light_storage->reflection_probe_get_origin_max_distance(p_instance->base);
3405 float atlas_size = RSG::light_storage->reflection_atlas_get_size(scenario->reflection_atlas);
3406 float mesh_lod_threshold = RSG::light_storage->reflection_probe_get_mesh_lod_threshold(p_instance->base) / atlas_size;
3407
3408 Vector3 edge = view_normals[p_step] * probe_size / 2;
3409 float distance = ABS(view_normals[p_step].dot(edge) - view_normals[p_step].dot(origin_offset)); //distance from origin offset to actual view distance limit
3410
3411 max_distance = MAX(max_distance, distance);
3412
3413 //render cubemap side
3414 Projection cm;
3415 cm.set_perspective(90, 1, 0.01, max_distance);
3416
3417 Transform3D local_view;
3418 local_view.set_look_at(origin_offset, origin_offset + view_normals[p_step], view_up[p_step]);
3419
3420 Transform3D xform = p_instance->transform * local_view;
3421
3422 RID shadow_atlas;
3423
3424 bool use_shadows = RSG::light_storage->reflection_probe_renders_shadows(p_instance->base);
3425 if (use_shadows) {
3426 shadow_atlas = scenario->reflection_probe_shadow_atlas;
3427 }
3428
3429 RID environment;
3430 if (scenario->environment.is_valid()) {
3431 environment = scenario->environment;
3432 } else {
3433 environment = scenario->fallback_environment;
3434 }
3435
3436 RENDER_TIMESTAMP("Render ReflectionProbe, Step " + itos(p_step));
3437 RendererSceneRender::CameraData camera_data;
3438 camera_data.set_camera(xform, cm, false, false);
3439
3440 Ref<RenderSceneBuffers> render_buffers = RSG::light_storage->reflection_probe_atlas_get_render_buffers(scenario->reflection_atlas);
3441 _render_scene(&camera_data, render_buffers, environment, RID(), RSG::light_storage->reflection_probe_get_cull_mask(p_instance->base), p_instance->scenario->self, RID(), shadow_atlas, reflection_probe->instance, p_step, mesh_lod_threshold, use_shadows);
3442
3443 } else {
3444 //do roughness postprocess step until it believes it's done
3445 RENDER_TIMESTAMP("Post-Process ReflectionProbe, Step " + itos(p_step));
3446 return RSG::light_storage->reflection_probe_instance_postprocess_step(reflection_probe->instance);
3447 }
3448
3449 return false;
3450}
3451
3452void RendererSceneCull::render_probes() {
3453 /* REFLECTION PROBES */
3454
3455 SelfList<InstanceReflectionProbeData> *ref_probe = reflection_probe_render_list.first();
3456
3457 bool busy = false;
3458
3459 while (ref_probe) {
3460 SelfList<InstanceReflectionProbeData> *next = ref_probe->next();
3461 RID base = ref_probe->self()->owner->base;
3462
3463 switch (RSG::light_storage->reflection_probe_get_update_mode(base)) {
3464 case RS::REFLECTION_PROBE_UPDATE_ONCE: {
3465 if (busy) { //already rendering something
3466 break;
3467 }
3468
3469 bool done = _render_reflection_probe_step(ref_probe->self()->owner, ref_probe->self()->render_step);
3470 if (done) {
3471 reflection_probe_render_list.remove(ref_probe);
3472 } else {
3473 ref_probe->self()->render_step++;
3474 }
3475
3476 busy = true; //do not render another one of this kind
3477 } break;
3478 case RS::REFLECTION_PROBE_UPDATE_ALWAYS: {
3479 int step = 0;
3480 bool done = false;
3481 while (!done) {
3482 done = _render_reflection_probe_step(ref_probe->self()->owner, step);
3483 step++;
3484 }
3485
3486 reflection_probe_render_list.remove(ref_probe);
3487 } break;
3488 }
3489
3490 ref_probe = next;
3491 }
3492
3493 /* VOXEL GIS */
3494
3495 SelfList<InstanceVoxelGIData> *voxel_gi = voxel_gi_update_list.first();
3496
3497 if (voxel_gi) {
3498 RENDER_TIMESTAMP("Render VoxelGI");
3499 }
3500
3501 while (voxel_gi) {
3502 SelfList<InstanceVoxelGIData> *next = voxel_gi->next();
3503
3504 InstanceVoxelGIData *probe = voxel_gi->self();
3505 //Instance *instance_probe = probe->owner;
3506
3507 //check if probe must be setup, but don't do if on the lighting thread
3508
3509 bool cache_dirty = false;
3510 int cache_count = 0;
3511 {
3512 int light_cache_size = probe->light_cache.size();
3513 const InstanceVoxelGIData::LightCache *caches = probe->light_cache.ptr();
3514 const RID *instance_caches = probe->light_instances.ptr();
3515
3516 int idx = 0; //must count visible lights
3517 for (Instance *E : probe->lights) {
3518 Instance *instance = E;
3519 InstanceLightData *instance_light = (InstanceLightData *)instance->base_data;
3520 if (!instance->visible) {
3521 continue;
3522 }
3523 if (cache_dirty) {
3524 //do nothing, since idx must count all visible lights anyway
3525 } else if (idx >= light_cache_size) {
3526 cache_dirty = true;
3527 } else {
3528 const InstanceVoxelGIData::LightCache *cache = &caches[idx];
3529
3530 if (
3531 instance_caches[idx] != instance_light->instance ||
3532 cache->has_shadow != RSG::light_storage->light_has_shadow(instance->base) ||
3533 cache->type != RSG::light_storage->light_get_type(instance->base) ||
3534 cache->transform != instance->transform ||
3535 cache->color != RSG::light_storage->light_get_color(instance->base) ||
3536 cache->energy != RSG::light_storage->light_get_param(instance->base, RS::LIGHT_PARAM_ENERGY) ||
3537 cache->intensity != RSG::light_storage->light_get_param(instance->base, RS::LIGHT_PARAM_INTENSITY) ||
3538 cache->bake_energy != RSG::light_storage->light_get_param(instance->base, RS::LIGHT_PARAM_INDIRECT_ENERGY) ||
3539 cache->radius != RSG::light_storage->light_get_param(instance->base, RS::LIGHT_PARAM_RANGE) ||
3540 cache->attenuation != RSG::light_storage->light_get_param(instance->base, RS::LIGHT_PARAM_ATTENUATION) ||
3541 cache->spot_angle != RSG::light_storage->light_get_param(instance->base, RS::LIGHT_PARAM_SPOT_ANGLE) ||
3542 cache->spot_attenuation != RSG::light_storage->light_get_param(instance->base, RS::LIGHT_PARAM_SPOT_ATTENUATION)) {
3543 cache_dirty = true;
3544 }
3545 }
3546
3547 idx++;
3548 }
3549
3550 for (const Instance *instance : probe->owner->scenario->directional_lights) {
3551 InstanceLightData *instance_light = (InstanceLightData *)instance->base_data;
3552 if (!instance->visible) {
3553 continue;
3554 }
3555 if (cache_dirty) {
3556 //do nothing, since idx must count all visible lights anyway
3557 } else if (idx >= light_cache_size) {
3558 cache_dirty = true;
3559 } else {
3560 const InstanceVoxelGIData::LightCache *cache = &caches[idx];
3561
3562 if (
3563 instance_caches[idx] != instance_light->instance ||
3564 cache->has_shadow != RSG::light_storage->light_has_shadow(instance->base) ||
3565 cache->type != RSG::light_storage->light_get_type(instance->base) ||
3566 cache->transform != instance->transform ||
3567 cache->color != RSG::light_storage->light_get_color(instance->base) ||
3568 cache->energy != RSG::light_storage->light_get_param(instance->base, RS::LIGHT_PARAM_ENERGY) ||
3569 cache->intensity != RSG::light_storage->light_get_param(instance->base, RS::LIGHT_PARAM_INTENSITY) ||
3570 cache->bake_energy != RSG::light_storage->light_get_param(instance->base, RS::LIGHT_PARAM_INDIRECT_ENERGY) ||
3571 cache->radius != RSG::light_storage->light_get_param(instance->base, RS::LIGHT_PARAM_RANGE) ||
3572 cache->attenuation != RSG::light_storage->light_get_param(instance->base, RS::LIGHT_PARAM_ATTENUATION) ||
3573 cache->spot_angle != RSG::light_storage->light_get_param(instance->base, RS::LIGHT_PARAM_SPOT_ANGLE) ||
3574 cache->spot_attenuation != RSG::light_storage->light_get_param(instance->base, RS::LIGHT_PARAM_SPOT_ATTENUATION) ||
3575 cache->sky_mode != RSG::light_storage->light_directional_get_sky_mode(instance->base)) {
3576 cache_dirty = true;
3577 }
3578 }
3579
3580 idx++;
3581 }
3582
3583 if (idx != light_cache_size) {
3584 cache_dirty = true;
3585 }
3586
3587 cache_count = idx;
3588 }
3589
3590 bool update_lights = scene_render->voxel_gi_needs_update(probe->probe_instance);
3591
3592 if (cache_dirty) {
3593 probe->light_cache.resize(cache_count);
3594 probe->light_instances.resize(cache_count);
3595
3596 if (cache_count) {
3597 InstanceVoxelGIData::LightCache *caches = probe->light_cache.ptrw();
3598 RID *instance_caches = probe->light_instances.ptrw();
3599
3600 int idx = 0; //must count visible lights
3601 for (Instance *E : probe->lights) {
3602 Instance *instance = E;
3603 InstanceLightData *instance_light = (InstanceLightData *)instance->base_data;
3604 if (!instance->visible) {
3605 continue;
3606 }
3607
3608 InstanceVoxelGIData::LightCache *cache = &caches[idx];
3609
3610 instance_caches[idx] = instance_light->instance;
3611 cache->has_shadow = RSG::light_storage->light_has_shadow(instance->base);
3612 cache->type = RSG::light_storage->light_get_type(instance->base);
3613 cache->transform = instance->transform;
3614 cache->color = RSG::light_storage->light_get_color(instance->base);
3615 cache->energy = RSG::light_storage->light_get_param(instance->base, RS::LIGHT_PARAM_ENERGY);
3616 cache->intensity = RSG::light_storage->light_get_param(instance->base, RS::LIGHT_PARAM_INTENSITY);
3617 cache->bake_energy = RSG::light_storage->light_get_param(instance->base, RS::LIGHT_PARAM_INDIRECT_ENERGY);
3618 cache->radius = RSG::light_storage->light_get_param(instance->base, RS::LIGHT_PARAM_RANGE);
3619 cache->attenuation = RSG::light_storage->light_get_param(instance->base, RS::LIGHT_PARAM_ATTENUATION);
3620 cache->spot_angle = RSG::light_storage->light_get_param(instance->base, RS::LIGHT_PARAM_SPOT_ANGLE);
3621 cache->spot_attenuation = RSG::light_storage->light_get_param(instance->base, RS::LIGHT_PARAM_SPOT_ATTENUATION);
3622
3623 idx++;
3624 }
3625 for (const Instance *instance : probe->owner->scenario->directional_lights) {
3626 InstanceLightData *instance_light = (InstanceLightData *)instance->base_data;
3627 if (!instance->visible) {
3628 continue;
3629 }
3630
3631 InstanceVoxelGIData::LightCache *cache = &caches[idx];
3632
3633 instance_caches[idx] = instance_light->instance;
3634 cache->has_shadow = RSG::light_storage->light_has_shadow(instance->base);
3635 cache->type = RSG::light_storage->light_get_type(instance->base);
3636 cache->transform = instance->transform;
3637 cache->color = RSG::light_storage->light_get_color(instance->base);
3638 cache->energy = RSG::light_storage->light_get_param(instance->base, RS::LIGHT_PARAM_ENERGY);
3639 cache->intensity = RSG::light_storage->light_get_param(instance->base, RS::LIGHT_PARAM_INTENSITY);
3640 cache->bake_energy = RSG::light_storage->light_get_param(instance->base, RS::LIGHT_PARAM_INDIRECT_ENERGY);
3641 cache->radius = RSG::light_storage->light_get_param(instance->base, RS::LIGHT_PARAM_RANGE);
3642 cache->attenuation = RSG::light_storage->light_get_param(instance->base, RS::LIGHT_PARAM_ATTENUATION);
3643 cache->spot_angle = RSG::light_storage->light_get_param(instance->base, RS::LIGHT_PARAM_SPOT_ANGLE);
3644 cache->spot_attenuation = RSG::light_storage->light_get_param(instance->base, RS::LIGHT_PARAM_SPOT_ATTENUATION);
3645 cache->sky_mode = RSG::light_storage->light_directional_get_sky_mode(instance->base);
3646
3647 idx++;
3648 }
3649 }
3650
3651 update_lights = true;
3652 }
3653
3654 scene_cull_result.geometry_instances.clear();
3655
3656 RID instance_pair_buffer[MAX_INSTANCE_PAIRS];
3657
3658 for (Instance *E : probe->dynamic_geometries) {
3659 Instance *ins = E;
3660 if (!ins->visible) {
3661 continue;
3662 }
3663 InstanceGeometryData *geom = (InstanceGeometryData *)ins->base_data;
3664
3665 if (ins->scenario && ins->array_index >= 0 && (ins->scenario->instance_data[ins->array_index].flags & InstanceData::FLAG_GEOM_VOXEL_GI_DIRTY)) {
3666 uint32_t idx = 0;
3667 for (const Instance *F : geom->voxel_gi_instances) {
3668 InstanceVoxelGIData *voxel_gi2 = static_cast<InstanceVoxelGIData *>(F->base_data);
3669
3670 instance_pair_buffer[idx++] = voxel_gi2->probe_instance;
3671 if (idx == MAX_INSTANCE_PAIRS) {
3672 break;
3673 }
3674 }
3675
3676 ERR_FAIL_NULL(geom->geometry_instance);
3677 geom->geometry_instance->pair_voxel_gi_instances(instance_pair_buffer, idx);
3678
3679 ins->scenario->instance_data[ins->array_index].flags &= ~uint32_t(InstanceData::FLAG_GEOM_VOXEL_GI_DIRTY);
3680 }
3681
3682 ERR_FAIL_NULL(geom->geometry_instance);
3683 scene_cull_result.geometry_instances.push_back(geom->geometry_instance);
3684 }
3685
3686 scene_render->voxel_gi_update(probe->probe_instance, update_lights, probe->light_instances, scene_cull_result.geometry_instances);
3687
3688 voxel_gi_update_list.remove(voxel_gi);
3689
3690 voxel_gi = next;
3691 }
3692}
3693
3694void RendererSceneCull::render_particle_colliders() {
3695 while (heightfield_particle_colliders_update_list.begin()) {
3696 Instance *hfpc = *heightfield_particle_colliders_update_list.begin();
3697
3698 if (hfpc->scenario && hfpc->base_type == RS::INSTANCE_PARTICLES_COLLISION && RSG::particles_storage->particles_collision_is_heightfield(hfpc->base)) {
3699 //update heightfield
3700 instance_cull_result.clear();
3701 scene_cull_result.geometry_instances.clear();
3702
3703 struct CullAABB {
3704 PagedArray<Instance *> *result;
3705 _FORCE_INLINE_ bool operator()(void *p_data) {
3706 Instance *p_instance = (Instance *)p_data;
3707 result->push_back(p_instance);
3708 return false;
3709 }
3710 };
3711
3712 CullAABB cull_aabb;
3713 cull_aabb.result = &instance_cull_result;
3714 hfpc->scenario->indexers[Scenario::INDEXER_GEOMETRY].aabb_query(hfpc->transformed_aabb, cull_aabb);
3715 hfpc->scenario->indexers[Scenario::INDEXER_VOLUMES].aabb_query(hfpc->transformed_aabb, cull_aabb);
3716
3717 for (int i = 0; i < (int)instance_cull_result.size(); i++) {
3718 Instance *instance = instance_cull_result[i];
3719 if (!instance || !((1 << instance->base_type) & (RS::INSTANCE_GEOMETRY_MASK & (~(1 << RS::INSTANCE_PARTICLES))))) { //all but particles to avoid self collision
3720 continue;
3721 }
3722 InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data);
3723 ERR_FAIL_NULL(geom->geometry_instance);
3724 scene_cull_result.geometry_instances.push_back(geom->geometry_instance);
3725 }
3726
3727 scene_render->render_particle_collider_heightfield(hfpc->base, hfpc->transform, scene_cull_result.geometry_instances);
3728 }
3729 heightfield_particle_colliders_update_list.remove(heightfield_particle_colliders_update_list.begin());
3730 }
3731}
3732
3733void RendererSceneCull::_update_instance_shader_uniforms_from_material(HashMap<StringName, Instance::InstanceShaderParameter> &isparams, const HashMap<StringName, Instance::InstanceShaderParameter> &existing_isparams, RID p_material) {
3734 List<RendererMaterialStorage::InstanceShaderParam> plist;
3735 RSG::material_storage->material_get_instance_shader_parameters(p_material, &plist);
3736 for (const RendererMaterialStorage::InstanceShaderParam &E : plist) {
3737 StringName name = E.info.name;
3738 if (isparams.has(name)) {
3739 if (isparams[name].info.type != E.info.type) {
3740 WARN_PRINT("More than one material in instance export the same instance shader uniform '" + E.info.name + "', but they do it with different data types. Only the first one (in order) will display correctly.");
3741 }
3742 if (isparams[name].index != E.index) {
3743 WARN_PRINT("More than one material in instance export the same instance shader uniform '" + E.info.name + "', but they do it with different indices. Only the first one (in order) will display correctly.");
3744 }
3745 continue; //first one found always has priority
3746 }
3747
3748 Instance::InstanceShaderParameter isp;
3749 isp.index = E.index;
3750 isp.info = E.info;
3751 isp.default_value = E.default_value;
3752 if (existing_isparams.has(name)) {
3753 isp.value = existing_isparams[name].value;
3754 } else {
3755 isp.value = E.default_value;
3756 }
3757 isparams[name] = isp;
3758 }
3759}
3760
3761void RendererSceneCull::_update_dirty_instance(Instance *p_instance) {
3762 if (p_instance->update_aabb) {
3763 _update_instance_aabb(p_instance);
3764 }
3765
3766 if (p_instance->update_dependencies) {
3767 p_instance->dependency_tracker.update_begin();
3768
3769 if (p_instance->base.is_valid()) {
3770 RSG::utilities->base_update_dependency(p_instance->base, &p_instance->dependency_tracker);
3771 }
3772
3773 if (p_instance->material_override.is_valid()) {
3774 RSG::material_storage->material_update_dependency(p_instance->material_override, &p_instance->dependency_tracker);
3775 }
3776
3777 if (p_instance->material_overlay.is_valid()) {
3778 RSG::material_storage->material_update_dependency(p_instance->material_overlay, &p_instance->dependency_tracker);
3779 }
3780
3781 if (p_instance->base_type == RS::INSTANCE_MESH) {
3782 //remove materials no longer used and un-own them
3783
3784 int new_mat_count = RSG::mesh_storage->mesh_get_surface_count(p_instance->base);
3785 p_instance->materials.resize(new_mat_count);
3786
3787 _instance_update_mesh_instance(p_instance);
3788 }
3789
3790 if (p_instance->base_type == RS::INSTANCE_PARTICLES) {
3791 // update the process material dependency
3792
3793 RID particle_material = RSG::particles_storage->particles_get_process_material(p_instance->base);
3794 if (particle_material.is_valid()) {
3795 RSG::material_storage->material_update_dependency(particle_material, &p_instance->dependency_tracker);
3796 }
3797 }
3798
3799 if ((1 << p_instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) {
3800 InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(p_instance->base_data);
3801
3802 bool can_cast_shadows = true;
3803 bool is_animated = false;
3804 HashMap<StringName, Instance::InstanceShaderParameter> isparams;
3805
3806 if (p_instance->cast_shadows == RS::SHADOW_CASTING_SETTING_OFF) {
3807 can_cast_shadows = false;
3808 }
3809
3810 if (p_instance->material_override.is_valid()) {
3811 if (!RSG::material_storage->material_casts_shadows(p_instance->material_override)) {
3812 can_cast_shadows = false;
3813 }
3814 is_animated = RSG::material_storage->material_is_animated(p_instance->material_override);
3815 _update_instance_shader_uniforms_from_material(isparams, p_instance->instance_shader_uniforms, p_instance->material_override);
3816 } else {
3817 if (p_instance->base_type == RS::INSTANCE_MESH) {
3818 RID mesh = p_instance->base;
3819
3820 if (mesh.is_valid()) {
3821 bool cast_shadows = false;
3822
3823 for (int i = 0; i < p_instance->materials.size(); i++) {
3824 RID mat = p_instance->materials[i].is_valid() ? p_instance->materials[i] : RSG::mesh_storage->mesh_surface_get_material(mesh, i);
3825
3826 if (!mat.is_valid()) {
3827 cast_shadows = true;
3828 } else {
3829 if (RSG::material_storage->material_casts_shadows(mat)) {
3830 cast_shadows = true;
3831 }
3832
3833 if (RSG::material_storage->material_is_animated(mat)) {
3834 is_animated = true;
3835 }
3836
3837 _update_instance_shader_uniforms_from_material(isparams, p_instance->instance_shader_uniforms, mat);
3838
3839 RSG::material_storage->material_update_dependency(mat, &p_instance->dependency_tracker);
3840 }
3841 }
3842
3843 if (!cast_shadows) {
3844 can_cast_shadows = false;
3845 }
3846 }
3847
3848 } else if (p_instance->base_type == RS::INSTANCE_MULTIMESH) {
3849 RID mesh = RSG::mesh_storage->multimesh_get_mesh(p_instance->base);
3850 if (mesh.is_valid()) {
3851 bool cast_shadows = false;
3852
3853 int sc = RSG::mesh_storage->mesh_get_surface_count(mesh);
3854 for (int i = 0; i < sc; i++) {
3855 RID mat = RSG::mesh_storage->mesh_surface_get_material(mesh, i);
3856
3857 if (!mat.is_valid()) {
3858 cast_shadows = true;
3859
3860 } else {
3861 if (RSG::material_storage->material_casts_shadows(mat)) {
3862 cast_shadows = true;
3863 }
3864 if (RSG::material_storage->material_is_animated(mat)) {
3865 is_animated = true;
3866 }
3867
3868 _update_instance_shader_uniforms_from_material(isparams, p_instance->instance_shader_uniforms, mat);
3869
3870 RSG::material_storage->material_update_dependency(mat, &p_instance->dependency_tracker);
3871 }
3872 }
3873
3874 if (!cast_shadows) {
3875 can_cast_shadows = false;
3876 }
3877
3878 RSG::utilities->base_update_dependency(mesh, &p_instance->dependency_tracker);
3879 }
3880 } else if (p_instance->base_type == RS::INSTANCE_PARTICLES) {
3881 bool cast_shadows = false;
3882
3883 int dp = RSG::particles_storage->particles_get_draw_passes(p_instance->base);
3884
3885 for (int i = 0; i < dp; i++) {
3886 RID mesh = RSG::particles_storage->particles_get_draw_pass_mesh(p_instance->base, i);
3887 if (!mesh.is_valid()) {
3888 continue;
3889 }
3890
3891 int sc = RSG::mesh_storage->mesh_get_surface_count(mesh);
3892 for (int j = 0; j < sc; j++) {
3893 RID mat = RSG::mesh_storage->mesh_surface_get_material(mesh, j);
3894
3895 if (!mat.is_valid()) {
3896 cast_shadows = true;
3897 } else {
3898 if (RSG::material_storage->material_casts_shadows(mat)) {
3899 cast_shadows = true;
3900 }
3901
3902 if (RSG::material_storage->material_is_animated(mat)) {
3903 is_animated = true;
3904 }
3905
3906 _update_instance_shader_uniforms_from_material(isparams, p_instance->instance_shader_uniforms, mat);
3907
3908 RSG::material_storage->material_update_dependency(mat, &p_instance->dependency_tracker);
3909 }
3910 }
3911 }
3912
3913 if (!cast_shadows) {
3914 can_cast_shadows = false;
3915 }
3916 }
3917 }
3918
3919 if (p_instance->material_overlay.is_valid()) {
3920 can_cast_shadows = can_cast_shadows && RSG::material_storage->material_casts_shadows(p_instance->material_overlay);
3921 is_animated = is_animated || RSG::material_storage->material_is_animated(p_instance->material_overlay);
3922 _update_instance_shader_uniforms_from_material(isparams, p_instance->instance_shader_uniforms, p_instance->material_overlay);
3923 }
3924
3925 if (can_cast_shadows != geom->can_cast_shadows) {
3926 //ability to cast shadows change, let lights now
3927 for (const Instance *E : geom->lights) {
3928 InstanceLightData *light = static_cast<InstanceLightData *>(E->base_data);
3929 light->shadow_dirty = true;
3930 }
3931
3932 geom->can_cast_shadows = can_cast_shadows;
3933 }
3934
3935 geom->material_is_animated = is_animated;
3936 p_instance->instance_shader_uniforms = isparams;
3937
3938 if (p_instance->instance_allocated_shader_uniforms != (p_instance->instance_shader_uniforms.size() > 0)) {
3939 p_instance->instance_allocated_shader_uniforms = (p_instance->instance_shader_uniforms.size() > 0);
3940 if (p_instance->instance_allocated_shader_uniforms) {
3941 p_instance->instance_allocated_shader_uniforms_offset = RSG::material_storage->global_shader_parameters_instance_allocate(p_instance->self);
3942 ERR_FAIL_NULL(geom->geometry_instance);
3943 geom->geometry_instance->set_instance_shader_uniforms_offset(p_instance->instance_allocated_shader_uniforms_offset);
3944
3945 for (const KeyValue<StringName, Instance::InstanceShaderParameter> &E : p_instance->instance_shader_uniforms) {
3946 if (E.value.value.get_type() != Variant::NIL) {
3947 int flags_count = 0;
3948 if (E.value.info.hint == PROPERTY_HINT_FLAGS) {
3949 // A small hack to detect boolean flags count and prevent overhead.
3950 switch (E.value.info.hint_string.length()) {
3951 case 3: // "x,y"
3952 flags_count = 1;
3953 break;
3954 case 5: // "x,y,z"
3955 flags_count = 2;
3956 break;
3957 case 7: // "x,y,z,w"
3958 flags_count = 3;
3959 break;
3960 }
3961 }
3962 RSG::material_storage->global_shader_parameters_instance_update(p_instance->self, E.value.index, E.value.value, flags_count);
3963 }
3964 }
3965 } else {
3966 RSG::material_storage->global_shader_parameters_instance_free(p_instance->self);
3967 p_instance->instance_allocated_shader_uniforms_offset = -1;
3968 ERR_FAIL_NULL(geom->geometry_instance);
3969 geom->geometry_instance->set_instance_shader_uniforms_offset(-1);
3970 }
3971 }
3972 }
3973
3974 if (p_instance->skeleton.is_valid()) {
3975 RSG::mesh_storage->skeleton_update_dependency(p_instance->skeleton, &p_instance->dependency_tracker);
3976 }
3977
3978 p_instance->dependency_tracker.update_end();
3979
3980 if ((1 << p_instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) {
3981 InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(p_instance->base_data);
3982 ERR_FAIL_NULL(geom->geometry_instance);
3983 geom->geometry_instance->set_surface_materials(p_instance->materials);
3984 }
3985 }
3986
3987 _instance_update_list.remove(&p_instance->update_item);
3988
3989 _update_instance(p_instance);
3990
3991 p_instance->update_aabb = false;
3992 p_instance->update_dependencies = false;
3993}
3994
3995void RendererSceneCull::update_dirty_instances() {
3996 while (_instance_update_list.first()) {
3997 _update_dirty_instance(_instance_update_list.first()->self());
3998 }
3999
4000 // Update dirty resources after dirty instances as instance updates may affect resources.
4001 RSG::utilities->update_dirty_resources();
4002}
4003
4004void RendererSceneCull::update() {
4005 //optimize bvhs
4006
4007 uint32_t rid_count = scenario_owner.get_rid_count();
4008 RID *rids = (RID *)alloca(sizeof(RID) * rid_count);
4009 scenario_owner.fill_owned_buffer(rids);
4010 for (uint32_t i = 0; i < rid_count; i++) {
4011 Scenario *s = scenario_owner.get_or_null(rids[i]);
4012 s->indexers[Scenario::INDEXER_GEOMETRY].optimize_incremental(indexer_update_iterations);
4013 s->indexers[Scenario::INDEXER_VOLUMES].optimize_incremental(indexer_update_iterations);
4014 }
4015 scene_render->update();
4016 update_dirty_instances();
4017 render_particle_colliders();
4018}
4019
4020bool RendererSceneCull::free(RID p_rid) {
4021 if (p_rid.is_null()) {
4022 return true;
4023 }
4024
4025 if (scene_render->free(p_rid)) {
4026 return true;
4027 }
4028
4029 if (camera_owner.owns(p_rid)) {
4030 camera_owner.free(p_rid);
4031
4032 } else if (scenario_owner.owns(p_rid)) {
4033 Scenario *scenario = scenario_owner.get_or_null(p_rid);
4034
4035 while (scenario->instances.first()) {
4036 instance_set_scenario(scenario->instances.first()->self()->self, RID());
4037 }
4038 scenario->instance_aabbs.reset();
4039 scenario->instance_data.reset();
4040 scenario->instance_visibility.reset();
4041
4042 RSG::light_storage->shadow_atlas_free(scenario->reflection_probe_shadow_atlas);
4043 RSG::light_storage->reflection_atlas_free(scenario->reflection_atlas);
4044 scenario_owner.free(p_rid);
4045 RendererSceneOcclusionCull::get_singleton()->remove_scenario(p_rid);
4046
4047 } else if (RendererSceneOcclusionCull::get_singleton()->is_occluder(p_rid)) {
4048 RendererSceneOcclusionCull::get_singleton()->free_occluder(p_rid);
4049 } else if (instance_owner.owns(p_rid)) {
4050 // delete the instance
4051
4052 update_dirty_instances();
4053
4054 Instance *instance = instance_owner.get_or_null(p_rid);
4055
4056 instance_geometry_set_lightmap(p_rid, RID(), Rect2(), 0);
4057 instance_set_scenario(p_rid, RID());
4058 instance_set_base(p_rid, RID());
4059 instance_geometry_set_material_override(p_rid, RID());
4060 instance_geometry_set_material_overlay(p_rid, RID());
4061 instance_attach_skeleton(p_rid, RID());
4062
4063 if (instance->instance_allocated_shader_uniforms) {
4064 //free the used shader parameters
4065 RSG::material_storage->global_shader_parameters_instance_free(instance->self);
4066 }
4067 update_dirty_instances(); //in case something changed this
4068
4069 instance_owner.free(p_rid);
4070 } else {
4071 return false;
4072 }
4073
4074 return true;
4075}
4076
4077TypedArray<Image> RendererSceneCull::bake_render_uv2(RID p_base, const TypedArray<RID> &p_material_overrides, const Size2i &p_image_size) {
4078 return scene_render->bake_render_uv2(p_base, p_material_overrides, p_image_size);
4079}
4080
4081void RendererSceneCull::update_visibility_notifiers() {
4082 SelfList<InstanceVisibilityNotifierData> *E = visible_notifier_list.first();
4083 while (E) {
4084 SelfList<InstanceVisibilityNotifierData> *N = E->next();
4085
4086 InstanceVisibilityNotifierData *visibility_notifier = E->self();
4087 if (visibility_notifier->just_visible) {
4088 visibility_notifier->just_visible = false;
4089
4090 RSG::utilities->visibility_notifier_call(visibility_notifier->base, true, RSG::threaded);
4091 } else {
4092 if (visibility_notifier->visible_in_frame != RSG::rasterizer->get_frame_number()) {
4093 visible_notifier_list.remove(E);
4094
4095 RSG::utilities->visibility_notifier_call(visibility_notifier->base, false, RSG::threaded);
4096 }
4097 }
4098
4099 E = N;
4100 }
4101}
4102
4103/*******************************/
4104/* Passthrough to Scene Render */
4105/*******************************/
4106
4107/* ENVIRONMENT API */
4108
4109RendererSceneCull *RendererSceneCull::singleton = nullptr;
4110
4111void RendererSceneCull::set_scene_render(RendererSceneRender *p_scene_render) {
4112 scene_render = p_scene_render;
4113 geometry_instance_pair_mask = scene_render->geometry_instance_get_pair_mask();
4114}
4115
4116float get_halton_value(int index, int base) {
4117 float f = 1;
4118 float r = 0;
4119 while (index > 0) {
4120 f = f / static_cast<float>(base);
4121 r = r + f * (index % base);
4122 index = index / base;
4123 }
4124 return r * 2.0f - 1.0f;
4125};
4126
4127RendererSceneCull::RendererSceneCull() {
4128 render_pass = 1;
4129 singleton = this;
4130
4131 instance_cull_result.set_page_pool(&instance_cull_page_pool);
4132 instance_shadow_cull_result.set_page_pool(&instance_cull_page_pool);
4133
4134 for (uint32_t i = 0; i < MAX_UPDATE_SHADOWS; i++) {
4135 render_shadow_data[i].instances.set_page_pool(&geometry_instance_cull_page_pool);
4136 }
4137 for (uint32_t i = 0; i < SDFGI_MAX_CASCADES * SDFGI_MAX_REGIONS_PER_CASCADE; i++) {
4138 render_sdfgi_data[i].instances.set_page_pool(&geometry_instance_cull_page_pool);
4139 }
4140
4141 scene_cull_result.init(&rid_cull_page_pool, &geometry_instance_cull_page_pool, &instance_cull_page_pool);
4142 scene_cull_result_threads.resize(WorkerThreadPool::get_singleton()->get_thread_count());
4143 for (InstanceCullResult &thread : scene_cull_result_threads) {
4144 thread.init(&rid_cull_page_pool, &geometry_instance_cull_page_pool, &instance_cull_page_pool);
4145 }
4146
4147 indexer_update_iterations = GLOBAL_GET("rendering/limits/spatial_indexer/update_iterations_per_frame");
4148 thread_cull_threshold = GLOBAL_GET("rendering/limits/spatial_indexer/threaded_cull_minimum_instances");
4149 thread_cull_threshold = MAX(thread_cull_threshold, (uint32_t)WorkerThreadPool::get_singleton()->get_thread_count()); //make sure there is at least one thread per CPU
4150
4151 taa_jitter_array.resize(TAA_JITTER_COUNT);
4152 for (int i = 0; i < TAA_JITTER_COUNT; i++) {
4153 taa_jitter_array[i].x = get_halton_value(i, 2);
4154 taa_jitter_array[i].y = get_halton_value(i, 3);
4155 }
4156
4157 dummy_occlusion_culling = memnew(RendererSceneOcclusionCull);
4158}
4159
4160RendererSceneCull::~RendererSceneCull() {
4161 instance_cull_result.reset();
4162 instance_shadow_cull_result.reset();
4163
4164 for (uint32_t i = 0; i < MAX_UPDATE_SHADOWS; i++) {
4165 render_shadow_data[i].instances.reset();
4166 }
4167 for (uint32_t i = 0; i < SDFGI_MAX_CASCADES * SDFGI_MAX_REGIONS_PER_CASCADE; i++) {
4168 render_sdfgi_data[i].instances.reset();
4169 }
4170
4171 scene_cull_result.reset();
4172 for (InstanceCullResult &thread : scene_cull_result_threads) {
4173 thread.reset();
4174 }
4175 scene_cull_result_threads.clear();
4176
4177 if (dummy_occlusion_culling) {
4178 memdelete(dummy_occlusion_culling);
4179 }
4180}
4181