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