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