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