| 1 | /**************************************************************************/ |
| 2 | /* renderer_scene_cull.h */ |
| 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 | #ifndef RENDERER_SCENE_CULL_H |
| 32 | #define RENDERER_SCENE_CULL_H |
| 33 | |
| 34 | #include "core/math/dynamic_bvh.h" |
| 35 | #include "core/templates/bin_sorted_array.h" |
| 36 | #include "core/templates/local_vector.h" |
| 37 | #include "core/templates/paged_allocator.h" |
| 38 | #include "core/templates/paged_array.h" |
| 39 | #include "core/templates/pass_func.h" |
| 40 | #include "core/templates/rid_owner.h" |
| 41 | #include "core/templates/self_list.h" |
| 42 | #include "servers/rendering/renderer_scene_occlusion_cull.h" |
| 43 | #include "servers/rendering/renderer_scene_render.h" |
| 44 | #include "servers/rendering/rendering_method.h" |
| 45 | #include "servers/rendering/rendering_server_globals.h" |
| 46 | #include "servers/rendering/storage/utilities.h" |
| 47 | #include "servers/xr/xr_interface.h" |
| 48 | |
| 49 | class RendererSceneCull : public RenderingMethod { |
| 50 | public: |
| 51 | RendererSceneRender *scene_render = nullptr; |
| 52 | |
| 53 | enum { |
| 54 | SDFGI_MAX_CASCADES = 8, |
| 55 | SDFGI_MAX_REGIONS_PER_CASCADE = 3, |
| 56 | MAX_INSTANCE_PAIRS = 32, |
| 57 | MAX_UPDATE_SHADOWS = 512 |
| 58 | }; |
| 59 | |
| 60 | uint64_t render_pass; |
| 61 | |
| 62 | static RendererSceneCull *singleton; |
| 63 | |
| 64 | /* CAMERA API */ |
| 65 | |
| 66 | struct Camera { |
| 67 | enum Type { |
| 68 | PERSPECTIVE, |
| 69 | ORTHOGONAL, |
| 70 | FRUSTUM |
| 71 | }; |
| 72 | Type type; |
| 73 | float fov; |
| 74 | float znear, zfar; |
| 75 | float size; |
| 76 | Vector2 offset; |
| 77 | uint32_t visible_layers; |
| 78 | bool vaspect; |
| 79 | RID env; |
| 80 | RID attributes; |
| 81 | |
| 82 | Transform3D transform; |
| 83 | |
| 84 | Camera() { |
| 85 | visible_layers = 0xFFFFFFFF; |
| 86 | fov = 75; |
| 87 | type = PERSPECTIVE; |
| 88 | znear = 0.05; |
| 89 | zfar = 4000; |
| 90 | size = 1.0; |
| 91 | offset = Vector2(); |
| 92 | vaspect = false; |
| 93 | } |
| 94 | }; |
| 95 | |
| 96 | mutable RID_Owner<Camera, true> camera_owner; |
| 97 | |
| 98 | virtual RID camera_allocate(); |
| 99 | virtual void camera_initialize(RID p_rid); |
| 100 | |
| 101 | virtual void camera_set_perspective(RID p_camera, float p_fovy_degrees, float p_z_near, float p_z_far); |
| 102 | virtual void camera_set_orthogonal(RID p_camera, float p_size, float p_z_near, float p_z_far); |
| 103 | virtual void camera_set_frustum(RID p_camera, float p_size, Vector2 p_offset, float p_z_near, float p_z_far); |
| 104 | virtual void camera_set_transform(RID p_camera, const Transform3D &p_transform); |
| 105 | virtual void camera_set_cull_mask(RID p_camera, uint32_t p_layers); |
| 106 | virtual void camera_set_environment(RID p_camera, RID p_env); |
| 107 | virtual void camera_set_camera_attributes(RID p_camera, RID p_attributes); |
| 108 | virtual void camera_set_use_vertical_aspect(RID p_camera, bool p_enable); |
| 109 | virtual bool is_camera(RID p_camera) const; |
| 110 | |
| 111 | /* OCCLUDER API */ |
| 112 | |
| 113 | virtual RID occluder_allocate(); |
| 114 | virtual void occluder_initialize(RID p_occluder); |
| 115 | virtual void occluder_set_mesh(RID p_occluder, const PackedVector3Array &p_vertices, const PackedInt32Array &p_indices); |
| 116 | |
| 117 | /* VISIBILITY NOTIFIER API */ |
| 118 | |
| 119 | RendererSceneOcclusionCull *dummy_occlusion_culling = nullptr; |
| 120 | |
| 121 | /* SCENARIO API */ |
| 122 | |
| 123 | struct Instance; |
| 124 | |
| 125 | struct PlaneSign { |
| 126 | _ALWAYS_INLINE_ PlaneSign() {} |
| 127 | _ALWAYS_INLINE_ PlaneSign(const Plane &p_plane) { |
| 128 | if (p_plane.normal.x > 0) { |
| 129 | signs[0] = 0; |
| 130 | } else { |
| 131 | signs[0] = 3; |
| 132 | } |
| 133 | if (p_plane.normal.y > 0) { |
| 134 | signs[1] = 1; |
| 135 | } else { |
| 136 | signs[1] = 4; |
| 137 | } |
| 138 | if (p_plane.normal.z > 0) { |
| 139 | signs[2] = 2; |
| 140 | } else { |
| 141 | signs[2] = 5; |
| 142 | } |
| 143 | } |
| 144 | |
| 145 | uint32_t signs[3]; |
| 146 | }; |
| 147 | |
| 148 | struct Frustum { |
| 149 | Vector<Plane> planes; |
| 150 | Vector<PlaneSign> plane_signs; |
| 151 | const Plane *planes_ptr; |
| 152 | const PlaneSign *plane_signs_ptr; |
| 153 | uint32_t plane_count; |
| 154 | |
| 155 | _ALWAYS_INLINE_ Frustum() {} |
| 156 | _ALWAYS_INLINE_ Frustum(const Frustum &p_frustum) { |
| 157 | planes = p_frustum.planes; |
| 158 | plane_signs = p_frustum.plane_signs; |
| 159 | |
| 160 | planes_ptr = planes.ptr(); |
| 161 | plane_signs_ptr = plane_signs.ptr(); |
| 162 | plane_count = p_frustum.plane_count; |
| 163 | } |
| 164 | _ALWAYS_INLINE_ void operator=(const Frustum &p_frustum) { |
| 165 | planes = p_frustum.planes; |
| 166 | plane_signs = p_frustum.plane_signs; |
| 167 | |
| 168 | planes_ptr = planes.ptr(); |
| 169 | plane_signs_ptr = plane_signs.ptr(); |
| 170 | plane_count = p_frustum.plane_count; |
| 171 | } |
| 172 | _ALWAYS_INLINE_ Frustum(const Vector<Plane> &p_planes) { |
| 173 | planes = p_planes; |
| 174 | planes_ptr = planes.ptrw(); |
| 175 | plane_count = planes.size(); |
| 176 | for (int i = 0; i < planes.size(); i++) { |
| 177 | PlaneSign ps(p_planes[i]); |
| 178 | plane_signs.push_back(ps); |
| 179 | } |
| 180 | |
| 181 | plane_signs_ptr = plane_signs.ptr(); |
| 182 | } |
| 183 | }; |
| 184 | |
| 185 | struct InstanceBounds { |
| 186 | // Efficiently store instance bounds. |
| 187 | // Because bounds checking is performed first, |
| 188 | // keep it separated from data. |
| 189 | |
| 190 | real_t bounds[6]; |
| 191 | _ALWAYS_INLINE_ InstanceBounds() {} |
| 192 | |
| 193 | _ALWAYS_INLINE_ InstanceBounds(const AABB &p_aabb) { |
| 194 | bounds[0] = p_aabb.position.x; |
| 195 | bounds[1] = p_aabb.position.y; |
| 196 | bounds[2] = p_aabb.position.z; |
| 197 | bounds[3] = p_aabb.position.x + p_aabb.size.x; |
| 198 | bounds[4] = p_aabb.position.y + p_aabb.size.y; |
| 199 | bounds[5] = p_aabb.position.z + p_aabb.size.z; |
| 200 | } |
| 201 | _ALWAYS_INLINE_ bool in_frustum(const Frustum &p_frustum) const { |
| 202 | // This is not a full SAT check and the possibility of false positives exist, |
| 203 | // but the tradeoff vs performance is still very good. |
| 204 | |
| 205 | for (uint32_t i = 0; i < p_frustum.plane_count; i++) { |
| 206 | Vector3 min( |
| 207 | bounds[p_frustum.plane_signs_ptr[i].signs[0]], |
| 208 | bounds[p_frustum.plane_signs_ptr[i].signs[1]], |
| 209 | bounds[p_frustum.plane_signs_ptr[i].signs[2]]); |
| 210 | |
| 211 | if (p_frustum.planes_ptr[i].distance_to(min) >= 0.0) { |
| 212 | return false; |
| 213 | } |
| 214 | } |
| 215 | |
| 216 | return true; |
| 217 | } |
| 218 | _ALWAYS_INLINE_ bool in_aabb(const AABB &p_aabb) const { |
| 219 | Vector3 end = p_aabb.position + p_aabb.size; |
| 220 | |
| 221 | if (bounds[0] >= end.x) { |
| 222 | return false; |
| 223 | } |
| 224 | if (bounds[3] <= p_aabb.position.x) { |
| 225 | return false; |
| 226 | } |
| 227 | if (bounds[1] >= end.y) { |
| 228 | return false; |
| 229 | } |
| 230 | if (bounds[4] <= p_aabb.position.y) { |
| 231 | return false; |
| 232 | } |
| 233 | if (bounds[2] >= end.z) { |
| 234 | return false; |
| 235 | } |
| 236 | if (bounds[5] <= p_aabb.position.z) { |
| 237 | return false; |
| 238 | } |
| 239 | |
| 240 | return true; |
| 241 | } |
| 242 | }; |
| 243 | |
| 244 | struct InstanceVisibilityNotifierData; |
| 245 | |
| 246 | struct InstanceData { |
| 247 | // Store instance pointer as well as common instance processing information, |
| 248 | // to make processing more cache friendly. |
| 249 | enum Flags { |
| 250 | FLAG_BASE_TYPE_MASK = 0xFF, |
| 251 | FLAG_CAST_SHADOWS = (1 << 8), |
| 252 | FLAG_CAST_SHADOWS_ONLY = (1 << 9), |
| 253 | FLAG_REDRAW_IF_VISIBLE = (1 << 10), |
| 254 | FLAG_GEOM_LIGHTING_DIRTY = (1 << 11), |
| 255 | FLAG_GEOM_REFLECTION_DIRTY = (1 << 12), |
| 256 | FLAG_GEOM_DECAL_DIRTY = (1 << 13), |
| 257 | FLAG_GEOM_VOXEL_GI_DIRTY = (1 << 14), |
| 258 | FLAG_LIGHTMAP_CAPTURE = (1 << 15), |
| 259 | FLAG_USES_BAKED_LIGHT = (1 << 16), |
| 260 | FLAG_USES_MESH_INSTANCE = (1 << 17), |
| 261 | FLAG_REFLECTION_PROBE_DIRTY = (1 << 18), |
| 262 | FLAG_IGNORE_OCCLUSION_CULLING = (1 << 19), |
| 263 | FLAG_VISIBILITY_DEPENDENCY_NEEDS_CHECK = (3 << 20), // 2 bits, overlaps with the other vis. dependency flags |
| 264 | FLAG_VISIBILITY_DEPENDENCY_HIDDEN_CLOSE_RANGE = (1 << 20), |
| 265 | FLAG_VISIBILITY_DEPENDENCY_HIDDEN = (1 << 21), |
| 266 | FLAG_VISIBILITY_DEPENDENCY_FADE_CHILDREN = (1 << 22), |
| 267 | FLAG_GEOM_PROJECTOR_SOFTSHADOW_DIRTY = (1 << 23), |
| 268 | FLAG_IGNORE_ALL_CULLING = (1 << 24), |
| 269 | }; |
| 270 | |
| 271 | uint32_t flags = 0; |
| 272 | uint32_t layer_mask = 0; //for fast layer-mask discard |
| 273 | RID base_rid; |
| 274 | union { |
| 275 | uint64_t instance_data_rid; |
| 276 | RenderGeometryInstance *instance_geometry; |
| 277 | InstanceVisibilityNotifierData *visibility_notifier = nullptr; |
| 278 | }; |
| 279 | Instance *instance = nullptr; |
| 280 | int32_t parent_array_index = -1; |
| 281 | int32_t visibility_index = -1; |
| 282 | }; |
| 283 | |
| 284 | struct InstanceVisibilityData { |
| 285 | uint64_t viewport_state = 0; |
| 286 | int32_t array_index = -1; |
| 287 | RS::VisibilityRangeFadeMode fade_mode = RS::VISIBILITY_RANGE_FADE_DISABLED; |
| 288 | Vector3 position; |
| 289 | Instance *instance = nullptr; |
| 290 | float range_begin = 0.0f; |
| 291 | float range_end = 0.0f; |
| 292 | float range_begin_margin = 0.0f; |
| 293 | float range_end_margin = 0.0f; |
| 294 | float children_fade_alpha = 1.0f; |
| 295 | }; |
| 296 | |
| 297 | class VisibilityArray : public BinSortedArray<InstanceVisibilityData> { |
| 298 | _FORCE_INLINE_ virtual void _update_idx(InstanceVisibilityData &r_element, uint64_t p_idx) { |
| 299 | r_element.instance->visibility_index = p_idx; |
| 300 | if (r_element.instance->scenario && r_element.instance->array_index != -1) { |
| 301 | r_element.instance->scenario->instance_data[r_element.instance->array_index].visibility_index = p_idx; |
| 302 | } |
| 303 | } |
| 304 | }; |
| 305 | |
| 306 | PagedArrayPool<InstanceBounds> instance_aabb_page_pool; |
| 307 | PagedArrayPool<InstanceData> instance_data_page_pool; |
| 308 | PagedArrayPool<InstanceVisibilityData> instance_visibility_data_page_pool; |
| 309 | |
| 310 | struct Scenario { |
| 311 | enum IndexerType { |
| 312 | INDEXER_GEOMETRY, //for geometry |
| 313 | INDEXER_VOLUMES, //for everything else |
| 314 | INDEXER_MAX |
| 315 | }; |
| 316 | |
| 317 | DynamicBVH indexers[INDEXER_MAX]; |
| 318 | |
| 319 | RID self; |
| 320 | |
| 321 | List<Instance *> directional_lights; |
| 322 | RID environment; |
| 323 | RID fallback_environment; |
| 324 | RID camera_attributes; |
| 325 | RID reflection_probe_shadow_atlas; |
| 326 | RID reflection_atlas; |
| 327 | uint64_t used_viewport_visibility_bits; |
| 328 | HashMap<RID, uint64_t> viewport_visibility_masks; |
| 329 | |
| 330 | SelfList<Instance>::List instances; |
| 331 | |
| 332 | LocalVector<RID> dynamic_lights; |
| 333 | |
| 334 | PagedArray<InstanceBounds> instance_aabbs; |
| 335 | PagedArray<InstanceData> instance_data; |
| 336 | VisibilityArray instance_visibility; |
| 337 | |
| 338 | Scenario() { |
| 339 | indexers[INDEXER_GEOMETRY].set_index(INDEXER_GEOMETRY); |
| 340 | indexers[INDEXER_VOLUMES].set_index(INDEXER_VOLUMES); |
| 341 | used_viewport_visibility_bits = 0; |
| 342 | } |
| 343 | }; |
| 344 | |
| 345 | int indexer_update_iterations = 0; |
| 346 | |
| 347 | mutable RID_Owner<Scenario, true> scenario_owner; |
| 348 | |
| 349 | static void _instance_pair(Instance *p_A, Instance *p_B); |
| 350 | static void _instance_unpair(Instance *p_A, Instance *p_B); |
| 351 | |
| 352 | void _instance_update_mesh_instance(Instance *p_instance); |
| 353 | |
| 354 | virtual RID scenario_allocate(); |
| 355 | virtual void scenario_initialize(RID p_rid); |
| 356 | |
| 357 | virtual void scenario_set_environment(RID p_scenario, RID p_environment); |
| 358 | virtual void scenario_set_camera_attributes(RID p_scenario, RID p_attributes); |
| 359 | virtual void scenario_set_fallback_environment(RID p_scenario, RID p_environment); |
| 360 | virtual void scenario_set_reflection_atlas_size(RID p_scenario, int p_reflection_size, int p_reflection_count); |
| 361 | virtual bool is_scenario(RID p_scenario) const; |
| 362 | virtual RID scenario_get_environment(RID p_scenario); |
| 363 | virtual void scenario_add_viewport_visibility_mask(RID p_scenario, RID p_viewport); |
| 364 | virtual void scenario_remove_viewport_visibility_mask(RID p_scenario, RID p_viewport); |
| 365 | |
| 366 | /* INSTANCING API */ |
| 367 | |
| 368 | struct InstancePair { |
| 369 | Instance *a = nullptr; |
| 370 | Instance *b = nullptr; |
| 371 | SelfList<InstancePair> list_a; |
| 372 | SelfList<InstancePair> list_b; |
| 373 | InstancePair() : |
| 374 | list_a(this), list_b(this) {} |
| 375 | }; |
| 376 | |
| 377 | PagedAllocator<InstancePair> pair_allocator; |
| 378 | |
| 379 | struct InstanceBaseData { |
| 380 | virtual ~InstanceBaseData() {} |
| 381 | }; |
| 382 | |
| 383 | struct Instance { |
| 384 | RS::InstanceType base_type; |
| 385 | RID base; |
| 386 | |
| 387 | RID skeleton; |
| 388 | RID material_override; |
| 389 | RID material_overlay; |
| 390 | |
| 391 | RID mesh_instance; //only used for meshes and when skeleton/blendshapes exist |
| 392 | |
| 393 | Transform3D transform; |
| 394 | |
| 395 | float lod_bias; |
| 396 | |
| 397 | bool ignore_occlusion_culling; |
| 398 | bool ignore_all_culling; |
| 399 | |
| 400 | Vector<RID> materials; |
| 401 | |
| 402 | RS::ShadowCastingSetting cast_shadows; |
| 403 | |
| 404 | uint32_t layer_mask; |
| 405 | //fit in 32 bits |
| 406 | bool mirror : 8; |
| 407 | bool receive_shadows : 8; |
| 408 | bool visible : 8; |
| 409 | bool baked_light : 2; //this flag is only to know if it actually did use baked light |
| 410 | bool dynamic_gi : 2; //same above for dynamic objects |
| 411 | bool redraw_if_visible : 4; |
| 412 | |
| 413 | Instance *lightmap = nullptr; |
| 414 | Rect2 lightmap_uv_scale; |
| 415 | int lightmap_slice_index; |
| 416 | uint32_t lightmap_cull_index; |
| 417 | Vector<Color> lightmap_sh; //spherical harmonic |
| 418 | |
| 419 | AABB aabb; |
| 420 | AABB transformed_aabb; |
| 421 | AABB prev_transformed_aabb; |
| 422 | |
| 423 | struct InstanceShaderParameter { |
| 424 | int32_t index = -1; |
| 425 | Variant value; |
| 426 | Variant default_value; |
| 427 | PropertyInfo info; |
| 428 | }; |
| 429 | |
| 430 | HashMap<StringName, InstanceShaderParameter> instance_shader_uniforms; |
| 431 | bool instance_allocated_shader_uniforms = false; |
| 432 | int32_t instance_allocated_shader_uniforms_offset = -1; |
| 433 | |
| 434 | // |
| 435 | |
| 436 | RID self; |
| 437 | //scenario stuff |
| 438 | DynamicBVH::ID indexer_id; |
| 439 | int32_t array_index = -1; |
| 440 | int32_t visibility_index = -1; |
| 441 | float visibility_range_begin = 0.0f; |
| 442 | float visibility_range_end = 0.0f; |
| 443 | float visibility_range_begin_margin = 0.0f; |
| 444 | float visibility_range_end_margin = 0.0f; |
| 445 | RS::VisibilityRangeFadeMode visibility_range_fade_mode = RS::VISIBILITY_RANGE_FADE_DISABLED; |
| 446 | Instance *visibility_parent = nullptr; |
| 447 | HashSet<Instance *> visibility_dependencies; |
| 448 | uint32_t visibility_dependencies_depth = 0; |
| 449 | float transparency = 0.0f; |
| 450 | Scenario *scenario = nullptr; |
| 451 | SelfList<Instance> scenario_item; |
| 452 | |
| 453 | //aabb stuff |
| 454 | bool update_aabb; |
| 455 | bool update_dependencies; |
| 456 | |
| 457 | SelfList<Instance> update_item; |
| 458 | |
| 459 | AABB *custom_aabb = nullptr; // <Zylann> would using aabb directly with a bool be better? |
| 460 | float ; |
| 461 | ObjectID object_id; |
| 462 | |
| 463 | // sorting |
| 464 | float sorting_offset = 0.0; |
| 465 | bool use_aabb_center = true; |
| 466 | |
| 467 | Vector<Color> lightmap_target_sh; //target is used for incrementally changing the SH over time, this avoids pops in some corner cases and when going interior <-> exterior |
| 468 | |
| 469 | uint64_t last_frame_pass; |
| 470 | |
| 471 | uint64_t version; // changes to this, and changes to base increase version |
| 472 | |
| 473 | InstanceBaseData *base_data = nullptr; |
| 474 | |
| 475 | SelfList<InstancePair>::List pairs; |
| 476 | uint64_t pair_check; |
| 477 | |
| 478 | DependencyTracker dependency_tracker; |
| 479 | |
| 480 | static void dependency_changed(Dependency::DependencyChangedNotification p_notification, DependencyTracker *tracker) { |
| 481 | Instance *instance = (Instance *)tracker->userdata; |
| 482 | switch (p_notification) { |
| 483 | case Dependency::DEPENDENCY_CHANGED_SKELETON_DATA: |
| 484 | case Dependency::DEPENDENCY_CHANGED_SKELETON_BONES: |
| 485 | case Dependency::DEPENDENCY_CHANGED_AABB: { |
| 486 | singleton->_instance_queue_update(instance, true, false); |
| 487 | |
| 488 | } break; |
| 489 | case Dependency::DEPENDENCY_CHANGED_MULTIMESH_VISIBLE_INSTANCES: |
| 490 | case Dependency::DEPENDENCY_CHANGED_MATERIAL: { |
| 491 | singleton->_instance_queue_update(instance, false, true); |
| 492 | } break; |
| 493 | case Dependency::DEPENDENCY_CHANGED_MESH: |
| 494 | case Dependency::DEPENDENCY_CHANGED_PARTICLES: |
| 495 | case Dependency::DEPENDENCY_CHANGED_MULTIMESH: |
| 496 | case Dependency::DEPENDENCY_CHANGED_DECAL: |
| 497 | case Dependency::DEPENDENCY_CHANGED_LIGHT: |
| 498 | case Dependency::DEPENDENCY_CHANGED_REFLECTION_PROBE: { |
| 499 | singleton->_instance_queue_update(instance, true, true); |
| 500 | } break; |
| 501 | case Dependency::DEPENDENCY_CHANGED_LIGHT_SOFT_SHADOW_AND_PROJECTOR: { |
| 502 | //requires repairing |
| 503 | if (instance->indexer_id.is_valid()) { |
| 504 | singleton->_unpair_instance(instance); |
| 505 | singleton->_instance_queue_update(instance, true, true); |
| 506 | } |
| 507 | |
| 508 | } break; |
| 509 | default: { |
| 510 | // Ignored notifications. |
| 511 | } break; |
| 512 | } |
| 513 | } |
| 514 | |
| 515 | static void dependency_deleted(const RID &p_dependency, DependencyTracker *tracker) { |
| 516 | Instance *instance = (Instance *)tracker->userdata; |
| 517 | |
| 518 | if (p_dependency == instance->base) { |
| 519 | singleton->instance_set_base(instance->self, RID()); |
| 520 | } else if (p_dependency == instance->skeleton) { |
| 521 | singleton->instance_attach_skeleton(instance->self, RID()); |
| 522 | } else { |
| 523 | // It's possible the same material is used in multiple slots, |
| 524 | // so we check whether we need to clear them all. |
| 525 | if (p_dependency == instance->material_override) { |
| 526 | singleton->instance_geometry_set_material_override(instance->self, RID()); |
| 527 | } |
| 528 | if (p_dependency == instance->material_overlay) { |
| 529 | singleton->instance_geometry_set_material_overlay(instance->self, RID()); |
| 530 | } |
| 531 | for (int i = 0; i < instance->materials.size(); i++) { |
| 532 | if (p_dependency == instance->materials[i]) { |
| 533 | singleton->instance_set_surface_override_material(instance->self, i, RID()); |
| 534 | } |
| 535 | } |
| 536 | if (instance->base_type == RS::INSTANCE_PARTICLES) { |
| 537 | RID particle_material = RSG::particles_storage->particles_get_process_material(instance->base); |
| 538 | if (p_dependency == particle_material) { |
| 539 | RSG::particles_storage->particles_set_process_material(instance->base, RID()); |
| 540 | } |
| 541 | } |
| 542 | |
| 543 | // Even if no change is made we still need to call `_instance_queue_update`. |
| 544 | // This dependency could also be a result of the freed material being used |
| 545 | // by the mesh this mesh instance uses. |
| 546 | singleton->_instance_queue_update(instance, false, true); |
| 547 | } |
| 548 | } |
| 549 | |
| 550 | Instance() : |
| 551 | scenario_item(this), |
| 552 | update_item(this) { |
| 553 | base_type = RS::INSTANCE_NONE; |
| 554 | cast_shadows = RS::SHADOW_CASTING_SETTING_ON; |
| 555 | receive_shadows = true; |
| 556 | visible = true; |
| 557 | layer_mask = 1; |
| 558 | baked_light = true; |
| 559 | dynamic_gi = false; |
| 560 | redraw_if_visible = false; |
| 561 | lightmap_slice_index = 0; |
| 562 | lightmap = nullptr; |
| 563 | lightmap_cull_index = 0; |
| 564 | lod_bias = 1.0; |
| 565 | ignore_occlusion_culling = false; |
| 566 | ignore_all_culling = false; |
| 567 | |
| 568 | scenario = nullptr; |
| 569 | |
| 570 | update_aabb = false; |
| 571 | update_dependencies = false; |
| 572 | |
| 573 | extra_margin = 0; |
| 574 | |
| 575 | visible = true; |
| 576 | |
| 577 | visibility_range_begin = 0; |
| 578 | visibility_range_end = 0; |
| 579 | visibility_range_begin_margin = 0; |
| 580 | visibility_range_end_margin = 0; |
| 581 | |
| 582 | last_frame_pass = 0; |
| 583 | version = 1; |
| 584 | base_data = nullptr; |
| 585 | |
| 586 | custom_aabb = nullptr; |
| 587 | |
| 588 | pair_check = 0; |
| 589 | array_index = -1; |
| 590 | |
| 591 | dependency_tracker.userdata = this; |
| 592 | dependency_tracker.changed_callback = dependency_changed; |
| 593 | dependency_tracker.deleted_callback = dependency_deleted; |
| 594 | } |
| 595 | |
| 596 | ~Instance() { |
| 597 | if (base_data) { |
| 598 | memdelete(base_data); |
| 599 | } |
| 600 | if (custom_aabb) { |
| 601 | memdelete(custom_aabb); |
| 602 | } |
| 603 | } |
| 604 | }; |
| 605 | |
| 606 | SelfList<Instance>::List _instance_update_list; |
| 607 | void _instance_queue_update(Instance *p_instance, bool p_update_aabb, bool p_update_dependencies = false); |
| 608 | |
| 609 | struct InstanceGeometryData : public InstanceBaseData { |
| 610 | RenderGeometryInstance *geometry_instance = nullptr; |
| 611 | HashSet<Instance *> lights; |
| 612 | bool can_cast_shadows; |
| 613 | bool material_is_animated; |
| 614 | uint32_t projector_count = 0; |
| 615 | uint32_t softshadow_count = 0; |
| 616 | |
| 617 | HashSet<Instance *> decals; |
| 618 | HashSet<Instance *> reflection_probes; |
| 619 | HashSet<Instance *> voxel_gi_instances; |
| 620 | HashSet<Instance *> lightmap_captures; |
| 621 | |
| 622 | InstanceGeometryData() { |
| 623 | can_cast_shadows = true; |
| 624 | material_is_animated = true; |
| 625 | } |
| 626 | }; |
| 627 | |
| 628 | struct InstanceReflectionProbeData : public InstanceBaseData { |
| 629 | Instance *owner = nullptr; |
| 630 | |
| 631 | HashSet<Instance *> geometries; |
| 632 | |
| 633 | RID instance; |
| 634 | SelfList<InstanceReflectionProbeData> update_list; |
| 635 | |
| 636 | int render_step; |
| 637 | |
| 638 | InstanceReflectionProbeData() : |
| 639 | update_list(this) { |
| 640 | render_step = -1; |
| 641 | } |
| 642 | }; |
| 643 | |
| 644 | struct InstanceDecalData : public InstanceBaseData { |
| 645 | Instance *owner = nullptr; |
| 646 | RID instance; |
| 647 | |
| 648 | HashSet<Instance *> geometries; |
| 649 | |
| 650 | InstanceDecalData() { |
| 651 | } |
| 652 | }; |
| 653 | |
| 654 | SelfList<InstanceReflectionProbeData>::List reflection_probe_render_list; |
| 655 | |
| 656 | struct InstanceParticlesCollisionData : public InstanceBaseData { |
| 657 | RID instance; |
| 658 | }; |
| 659 | |
| 660 | struct InstanceFogVolumeData : public InstanceBaseData { |
| 661 | RID instance; |
| 662 | bool is_global; |
| 663 | }; |
| 664 | |
| 665 | struct InstanceVisibilityNotifierData : public InstanceBaseData { |
| 666 | bool just_visible = false; |
| 667 | uint64_t visible_in_frame = 0; |
| 668 | RID base; |
| 669 | SelfList<InstanceVisibilityNotifierData> list_element; |
| 670 | InstanceVisibilityNotifierData() : |
| 671 | list_element(this) {} |
| 672 | }; |
| 673 | |
| 674 | SpinLock visible_notifier_list_lock; |
| 675 | SelfList<InstanceVisibilityNotifierData>::List visible_notifier_list; |
| 676 | |
| 677 | struct InstanceLightData : public InstanceBaseData { |
| 678 | RID instance; |
| 679 | uint64_t last_version; |
| 680 | List<Instance *>::Element *D; // directional light in scenario |
| 681 | |
| 682 | bool shadow_dirty; |
| 683 | bool uses_projector = false; |
| 684 | bool uses_softshadow = false; |
| 685 | |
| 686 | HashSet<Instance *> geometries; |
| 687 | |
| 688 | Instance *baked_light = nullptr; |
| 689 | |
| 690 | RS::LightBakeMode bake_mode; |
| 691 | uint32_t max_sdfgi_cascade = 2; |
| 692 | |
| 693 | InstanceLightData() { |
| 694 | bake_mode = RS::LIGHT_BAKE_DISABLED; |
| 695 | shadow_dirty = true; |
| 696 | D = nullptr; |
| 697 | last_version = 0; |
| 698 | baked_light = nullptr; |
| 699 | } |
| 700 | }; |
| 701 | |
| 702 | struct InstanceVoxelGIData : public InstanceBaseData { |
| 703 | Instance *owner = nullptr; |
| 704 | |
| 705 | HashSet<Instance *> geometries; |
| 706 | HashSet<Instance *> dynamic_geometries; |
| 707 | |
| 708 | HashSet<Instance *> lights; |
| 709 | |
| 710 | struct LightCache { |
| 711 | RS::LightType type; |
| 712 | Transform3D transform; |
| 713 | Color color; |
| 714 | float energy; |
| 715 | float intensity; |
| 716 | float bake_energy; |
| 717 | float radius; |
| 718 | float attenuation; |
| 719 | float spot_angle; |
| 720 | float spot_attenuation; |
| 721 | bool has_shadow; |
| 722 | RS::LightDirectionalSkyMode sky_mode; |
| 723 | }; |
| 724 | |
| 725 | Vector<LightCache> light_cache; |
| 726 | Vector<RID> light_instances; |
| 727 | |
| 728 | RID probe_instance; |
| 729 | |
| 730 | bool invalid; |
| 731 | uint32_t base_version; |
| 732 | |
| 733 | SelfList<InstanceVoxelGIData> update_element; |
| 734 | |
| 735 | InstanceVoxelGIData() : |
| 736 | update_element(this) { |
| 737 | invalid = true; |
| 738 | base_version = 0; |
| 739 | } |
| 740 | }; |
| 741 | |
| 742 | SelfList<InstanceVoxelGIData>::List voxel_gi_update_list; |
| 743 | |
| 744 | struct InstanceLightmapData : public InstanceBaseData { |
| 745 | RID instance; |
| 746 | HashSet<Instance *> geometries; |
| 747 | HashSet<Instance *> users; |
| 748 | |
| 749 | InstanceLightmapData() { |
| 750 | } |
| 751 | }; |
| 752 | |
| 753 | uint64_t pair_pass = 1; |
| 754 | |
| 755 | struct PairInstances { |
| 756 | Instance *instance = nullptr; |
| 757 | PagedAllocator<InstancePair> *pair_allocator = nullptr; |
| 758 | SelfList<InstancePair>::List pairs_found; |
| 759 | DynamicBVH *bvh = nullptr; |
| 760 | DynamicBVH *bvh2 = nullptr; //some may need to cull in two |
| 761 | uint32_t pair_mask; |
| 762 | uint64_t pair_pass; |
| 763 | uint32_t cull_mask = 0xFFFFFFFF; // Needed for decals and lights in the mobile and compatibility renderers. |
| 764 | |
| 765 | _FORCE_INLINE_ bool operator()(void *p_data) { |
| 766 | Instance *p_instance = (Instance *)p_data; |
| 767 | |
| 768 | if (instance != p_instance && instance->transformed_aabb.intersects(p_instance->transformed_aabb) && (pair_mask & (1 << p_instance->base_type)) && (cull_mask & p_instance->layer_mask)) { |
| 769 | //test is more coarse in indexer |
| 770 | p_instance->pair_check = pair_pass; |
| 771 | InstancePair *pair = pair_allocator->alloc(); |
| 772 | pair->a = instance; |
| 773 | pair->b = p_instance; |
| 774 | pairs_found.add(&pair->list_a); |
| 775 | } |
| 776 | return false; |
| 777 | } |
| 778 | |
| 779 | void pair() { |
| 780 | if (bvh) { |
| 781 | bvh->aabb_query(instance->transformed_aabb, *this); |
| 782 | } |
| 783 | if (bvh2) { |
| 784 | bvh2->aabb_query(instance->transformed_aabb, *this); |
| 785 | } |
| 786 | while (instance->pairs.first()) { |
| 787 | InstancePair *pair = instance->pairs.first()->self(); |
| 788 | Instance *other_instance = instance == pair->a ? pair->b : pair->a; |
| 789 | if (other_instance->pair_check != pair_pass) { |
| 790 | //unpaired |
| 791 | _instance_unpair(instance, other_instance); |
| 792 | } else { |
| 793 | //kept |
| 794 | other_instance->pair_check = 0; // if kept, then put pair check to zero, so we can distinguish with the newly added ones |
| 795 | } |
| 796 | |
| 797 | pair_allocator->free(pair); |
| 798 | } |
| 799 | while (pairs_found.first()) { |
| 800 | InstancePair *pair = pairs_found.first()->self(); |
| 801 | pairs_found.remove(pairs_found.first()); |
| 802 | |
| 803 | if (pair->b->pair_check == pair_pass) { |
| 804 | //paired |
| 805 | _instance_pair(instance, pair->b); |
| 806 | } |
| 807 | pair->a->pairs.add(&pair->list_a); |
| 808 | pair->b->pairs.add(&pair->list_b); |
| 809 | } |
| 810 | } |
| 811 | }; |
| 812 | |
| 813 | HashSet<Instance *> heightfield_particle_colliders_update_list; |
| 814 | |
| 815 | PagedArrayPool<Instance *> instance_cull_page_pool; |
| 816 | PagedArrayPool<RenderGeometryInstance *> geometry_instance_cull_page_pool; |
| 817 | PagedArrayPool<RID> rid_cull_page_pool; |
| 818 | |
| 819 | PagedArray<Instance *> instance_cull_result; |
| 820 | PagedArray<Instance *> instance_shadow_cull_result; |
| 821 | |
| 822 | struct InstanceCullResult { |
| 823 | PagedArray<RenderGeometryInstance *> geometry_instances; |
| 824 | PagedArray<Instance *> lights; |
| 825 | PagedArray<RID> light_instances; |
| 826 | PagedArray<RID> lightmaps; |
| 827 | PagedArray<RID> reflections; |
| 828 | PagedArray<RID> decals; |
| 829 | PagedArray<RID> voxel_gi_instances; |
| 830 | PagedArray<RID> mesh_instances; |
| 831 | PagedArray<RID> fog_volumes; |
| 832 | |
| 833 | struct DirectionalShadow { |
| 834 | PagedArray<RenderGeometryInstance *> cascade_geometry_instances[RendererSceneRender::MAX_DIRECTIONAL_LIGHT_CASCADES]; |
| 835 | } directional_shadows[RendererSceneRender::MAX_DIRECTIONAL_LIGHTS]; |
| 836 | |
| 837 | PagedArray<RenderGeometryInstance *> sdfgi_region_geometry_instances[SDFGI_MAX_CASCADES * SDFGI_MAX_REGIONS_PER_CASCADE]; |
| 838 | PagedArray<RID> sdfgi_cascade_lights[SDFGI_MAX_CASCADES]; |
| 839 | |
| 840 | void clear() { |
| 841 | geometry_instances.clear(); |
| 842 | lights.clear(); |
| 843 | light_instances.clear(); |
| 844 | lightmaps.clear(); |
| 845 | reflections.clear(); |
| 846 | decals.clear(); |
| 847 | voxel_gi_instances.clear(); |
| 848 | mesh_instances.clear(); |
| 849 | fog_volumes.clear(); |
| 850 | for (int i = 0; i < RendererSceneRender::MAX_DIRECTIONAL_LIGHTS; i++) { |
| 851 | for (int j = 0; j < RendererSceneRender::MAX_DIRECTIONAL_LIGHT_CASCADES; j++) { |
| 852 | directional_shadows[i].cascade_geometry_instances[j].clear(); |
| 853 | } |
| 854 | } |
| 855 | |
| 856 | for (int i = 0; i < SDFGI_MAX_CASCADES * SDFGI_MAX_REGIONS_PER_CASCADE; i++) { |
| 857 | sdfgi_region_geometry_instances[i].clear(); |
| 858 | } |
| 859 | |
| 860 | for (int i = 0; i < SDFGI_MAX_CASCADES; i++) { |
| 861 | sdfgi_cascade_lights[i].clear(); |
| 862 | } |
| 863 | } |
| 864 | |
| 865 | void reset() { |
| 866 | geometry_instances.reset(); |
| 867 | lights.reset(); |
| 868 | light_instances.reset(); |
| 869 | lightmaps.reset(); |
| 870 | reflections.reset(); |
| 871 | decals.reset(); |
| 872 | voxel_gi_instances.reset(); |
| 873 | mesh_instances.reset(); |
| 874 | fog_volumes.reset(); |
| 875 | for (int i = 0; i < RendererSceneRender::MAX_DIRECTIONAL_LIGHTS; i++) { |
| 876 | for (int j = 0; j < RendererSceneRender::MAX_DIRECTIONAL_LIGHT_CASCADES; j++) { |
| 877 | directional_shadows[i].cascade_geometry_instances[j].reset(); |
| 878 | } |
| 879 | } |
| 880 | |
| 881 | for (int i = 0; i < SDFGI_MAX_CASCADES * SDFGI_MAX_REGIONS_PER_CASCADE; i++) { |
| 882 | sdfgi_region_geometry_instances[i].reset(); |
| 883 | } |
| 884 | |
| 885 | for (int i = 0; i < SDFGI_MAX_CASCADES; i++) { |
| 886 | sdfgi_cascade_lights[i].reset(); |
| 887 | } |
| 888 | } |
| 889 | |
| 890 | void append_from(InstanceCullResult &p_cull_result) { |
| 891 | geometry_instances.merge_unordered(p_cull_result.geometry_instances); |
| 892 | lights.merge_unordered(p_cull_result.lights); |
| 893 | light_instances.merge_unordered(p_cull_result.light_instances); |
| 894 | lightmaps.merge_unordered(p_cull_result.lightmaps); |
| 895 | reflections.merge_unordered(p_cull_result.reflections); |
| 896 | decals.merge_unordered(p_cull_result.decals); |
| 897 | voxel_gi_instances.merge_unordered(p_cull_result.voxel_gi_instances); |
| 898 | mesh_instances.merge_unordered(p_cull_result.mesh_instances); |
| 899 | fog_volumes.merge_unordered(p_cull_result.fog_volumes); |
| 900 | |
| 901 | for (int i = 0; i < RendererSceneRender::MAX_DIRECTIONAL_LIGHTS; i++) { |
| 902 | for (int j = 0; j < RendererSceneRender::MAX_DIRECTIONAL_LIGHT_CASCADES; j++) { |
| 903 | directional_shadows[i].cascade_geometry_instances[j].merge_unordered(p_cull_result.directional_shadows[i].cascade_geometry_instances[j]); |
| 904 | } |
| 905 | } |
| 906 | |
| 907 | for (int i = 0; i < SDFGI_MAX_CASCADES * SDFGI_MAX_REGIONS_PER_CASCADE; i++) { |
| 908 | sdfgi_region_geometry_instances[i].merge_unordered(p_cull_result.sdfgi_region_geometry_instances[i]); |
| 909 | } |
| 910 | |
| 911 | for (int i = 0; i < SDFGI_MAX_CASCADES; i++) { |
| 912 | sdfgi_cascade_lights[i].merge_unordered(p_cull_result.sdfgi_cascade_lights[i]); |
| 913 | } |
| 914 | } |
| 915 | |
| 916 | void init(PagedArrayPool<RID> *p_rid_pool, PagedArrayPool<RenderGeometryInstance *> *p_geometry_instance_pool, PagedArrayPool<Instance *> *p_instance_pool) { |
| 917 | geometry_instances.set_page_pool(p_geometry_instance_pool); |
| 918 | light_instances.set_page_pool(p_rid_pool); |
| 919 | lights.set_page_pool(p_instance_pool); |
| 920 | lightmaps.set_page_pool(p_rid_pool); |
| 921 | reflections.set_page_pool(p_rid_pool); |
| 922 | decals.set_page_pool(p_rid_pool); |
| 923 | voxel_gi_instances.set_page_pool(p_rid_pool); |
| 924 | mesh_instances.set_page_pool(p_rid_pool); |
| 925 | fog_volumes.set_page_pool(p_rid_pool); |
| 926 | for (int i = 0; i < RendererSceneRender::MAX_DIRECTIONAL_LIGHTS; i++) { |
| 927 | for (int j = 0; j < RendererSceneRender::MAX_DIRECTIONAL_LIGHT_CASCADES; j++) { |
| 928 | directional_shadows[i].cascade_geometry_instances[j].set_page_pool(p_geometry_instance_pool); |
| 929 | } |
| 930 | } |
| 931 | |
| 932 | for (int i = 0; i < SDFGI_MAX_CASCADES * SDFGI_MAX_REGIONS_PER_CASCADE; i++) { |
| 933 | sdfgi_region_geometry_instances[i].set_page_pool(p_geometry_instance_pool); |
| 934 | } |
| 935 | |
| 936 | for (int i = 0; i < SDFGI_MAX_CASCADES; i++) { |
| 937 | sdfgi_cascade_lights[i].set_page_pool(p_rid_pool); |
| 938 | } |
| 939 | } |
| 940 | }; |
| 941 | |
| 942 | InstanceCullResult scene_cull_result; |
| 943 | LocalVector<InstanceCullResult> scene_cull_result_threads; |
| 944 | |
| 945 | RendererSceneRender::RenderShadowData render_shadow_data[MAX_UPDATE_SHADOWS]; |
| 946 | uint32_t max_shadows_used = 0; |
| 947 | |
| 948 | RendererSceneRender::RenderSDFGIData render_sdfgi_data[SDFGI_MAX_CASCADES * SDFGI_MAX_REGIONS_PER_CASCADE]; |
| 949 | RendererSceneRender::RenderSDFGIUpdateData sdfgi_update_data; |
| 950 | |
| 951 | uint32_t thread_cull_threshold = 200; |
| 952 | |
| 953 | RID_Owner<Instance, true> instance_owner; |
| 954 | |
| 955 | uint32_t geometry_instance_pair_mask = 0; // used in traditional forward, unnecessary on clustered |
| 956 | |
| 957 | const int TAA_JITTER_COUNT = 16; |
| 958 | LocalVector<Vector2> taa_jitter_array; |
| 959 | |
| 960 | virtual RID instance_allocate(); |
| 961 | virtual void instance_initialize(RID p_rid); |
| 962 | |
| 963 | virtual void instance_set_base(RID p_instance, RID p_base); |
| 964 | virtual void instance_set_scenario(RID p_instance, RID p_scenario); |
| 965 | virtual void instance_set_layer_mask(RID p_instance, uint32_t p_mask); |
| 966 | virtual void instance_set_pivot_data(RID p_instance, float p_sorting_offset, bool p_use_aabb_center); |
| 967 | virtual void instance_set_transform(RID p_instance, const Transform3D &p_transform); |
| 968 | virtual void instance_attach_object_instance_id(RID p_instance, ObjectID p_id); |
| 969 | virtual void instance_set_blend_shape_weight(RID p_instance, int p_shape, float p_weight); |
| 970 | virtual void instance_set_surface_override_material(RID p_instance, int p_surface, RID p_material); |
| 971 | virtual void instance_set_visible(RID p_instance, bool p_visible); |
| 972 | virtual void instance_geometry_set_transparency(RID p_instance, float p_transparency); |
| 973 | |
| 974 | virtual void instance_set_custom_aabb(RID p_instance, AABB p_aabb); |
| 975 | |
| 976 | virtual void instance_attach_skeleton(RID p_instance, RID p_skeleton); |
| 977 | |
| 978 | virtual void (RID p_instance, real_t p_margin); |
| 979 | |
| 980 | virtual void instance_set_visibility_parent(RID p_instance, RID p_parent_instance); |
| 981 | |
| 982 | virtual void instance_set_ignore_culling(RID p_instance, bool p_enabled); |
| 983 | |
| 984 | bool _update_instance_visibility_depth(Instance *p_instance); |
| 985 | void _update_instance_visibility_dependencies(Instance *p_instance); |
| 986 | |
| 987 | // don't use these in a game! |
| 988 | virtual Vector<ObjectID> instances_cull_aabb(const AABB &p_aabb, RID p_scenario = RID()) const; |
| 989 | virtual Vector<ObjectID> instances_cull_ray(const Vector3 &p_from, const Vector3 &p_to, RID p_scenario = RID()) const; |
| 990 | virtual Vector<ObjectID> instances_cull_convex(const Vector<Plane> &p_convex, RID p_scenario = RID()) const; |
| 991 | |
| 992 | virtual void instance_geometry_set_flag(RID p_instance, RS::InstanceFlags p_flags, bool p_enabled); |
| 993 | virtual void instance_geometry_set_cast_shadows_setting(RID p_instance, RS::ShadowCastingSetting p_shadow_casting_setting); |
| 994 | virtual void instance_geometry_set_material_override(RID p_instance, RID p_material); |
| 995 | virtual void instance_geometry_set_material_overlay(RID p_instance, RID p_material); |
| 996 | |
| 997 | virtual void 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); |
| 998 | |
| 999 | virtual void instance_geometry_set_lightmap(RID p_instance, RID p_lightmap, const Rect2 &p_lightmap_uv_scale, int p_slice_index); |
| 1000 | virtual void instance_geometry_set_lod_bias(RID p_instance, float p_lod_bias); |
| 1001 | |
| 1002 | void _update_instance_shader_uniforms_from_material(HashMap<StringName, Instance::InstanceShaderParameter> &isparams, const HashMap<StringName, Instance::InstanceShaderParameter> &existing_isparams, RID p_material); |
| 1003 | |
| 1004 | virtual void instance_geometry_set_shader_parameter(RID p_instance, const StringName &p_parameter, const Variant &p_value); |
| 1005 | virtual void instance_geometry_get_shader_parameter_list(RID p_instance, List<PropertyInfo> *p_parameters) const; |
| 1006 | virtual Variant instance_geometry_get_shader_parameter(RID p_instance, const StringName &p_parameter) const; |
| 1007 | virtual Variant instance_geometry_get_shader_parameter_default_value(RID p_instance, const StringName &p_parameter) const; |
| 1008 | |
| 1009 | _FORCE_INLINE_ void _update_instance(Instance *p_instance); |
| 1010 | _FORCE_INLINE_ void _update_instance_aabb(Instance *p_instance); |
| 1011 | _FORCE_INLINE_ void _update_dirty_instance(Instance *p_instance); |
| 1012 | _FORCE_INLINE_ void _update_instance_lightmap_captures(Instance *p_instance); |
| 1013 | void _unpair_instance(Instance *p_instance); |
| 1014 | |
| 1015 | void _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); |
| 1016 | |
| 1017 | _FORCE_INLINE_ bool _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_scren_mesh_lod_threshold, uint32_t p_visible_layers = 0xFFFFFF); |
| 1018 | |
| 1019 | RID _render_get_environment(RID p_camera, RID p_scenario); |
| 1020 | |
| 1021 | struct Cull { |
| 1022 | struct Shadow { |
| 1023 | RID light_instance; |
| 1024 | struct Cascade { |
| 1025 | Frustum frustum; |
| 1026 | |
| 1027 | Projection projection; |
| 1028 | Transform3D transform; |
| 1029 | real_t zfar; |
| 1030 | real_t split; |
| 1031 | real_t shadow_texel_size; |
| 1032 | real_t bias_scale; |
| 1033 | real_t range_begin; |
| 1034 | Vector2 uv_scale; |
| 1035 | |
| 1036 | } cascades[RendererSceneRender::MAX_DIRECTIONAL_LIGHT_CASCADES]; //max 4 cascades |
| 1037 | uint32_t cascade_count; |
| 1038 | |
| 1039 | } shadows[RendererSceneRender::MAX_DIRECTIONAL_LIGHTS]; |
| 1040 | |
| 1041 | uint32_t shadow_count; |
| 1042 | |
| 1043 | struct SDFGI { |
| 1044 | //have arrays here because SDFGI functions expects this, plus regions can have areas |
| 1045 | AABB region_aabb[SDFGI_MAX_CASCADES * SDFGI_MAX_REGIONS_PER_CASCADE]; //max 3 regions per cascade |
| 1046 | uint32_t region_cascade[SDFGI_MAX_CASCADES * SDFGI_MAX_REGIONS_PER_CASCADE]; //max 3 regions per cascade |
| 1047 | uint32_t region_count = 0; |
| 1048 | |
| 1049 | uint32_t cascade_light_index[SDFGI_MAX_CASCADES]; |
| 1050 | uint32_t cascade_light_count = 0; |
| 1051 | |
| 1052 | } sdfgi; |
| 1053 | |
| 1054 | SpinLock lock; |
| 1055 | |
| 1056 | Frustum frustum; |
| 1057 | } cull; |
| 1058 | |
| 1059 | struct VisibilityCullData { |
| 1060 | uint64_t viewport_mask; |
| 1061 | Scenario *scenario = nullptr; |
| 1062 | Vector3 camera_position; |
| 1063 | uint32_t cull_offset; |
| 1064 | uint32_t cull_count; |
| 1065 | }; |
| 1066 | |
| 1067 | void _visibility_cull_threaded(uint32_t p_thread, VisibilityCullData *cull_data); |
| 1068 | void _visibility_cull(const VisibilityCullData &cull_data, uint64_t p_from, uint64_t p_to); |
| 1069 | template <bool p_fade_check> |
| 1070 | _FORCE_INLINE_ int _visibility_range_check(InstanceVisibilityData &r_vis_data, const Vector3 &p_camera_pos, uint64_t p_viewport_mask); |
| 1071 | |
| 1072 | struct CullData { |
| 1073 | Cull *cull = nullptr; |
| 1074 | Scenario *scenario = nullptr; |
| 1075 | RID shadow_atlas; |
| 1076 | Transform3D cam_transform; |
| 1077 | uint32_t visible_layers; |
| 1078 | Instance *render_reflection_probe = nullptr; |
| 1079 | const RendererSceneOcclusionCull::HZBuffer *occlusion_buffer; |
| 1080 | const Projection *camera_matrix; |
| 1081 | uint64_t visibility_viewport_mask; |
| 1082 | }; |
| 1083 | |
| 1084 | void _scene_cull_threaded(uint32_t p_thread, CullData *cull_data); |
| 1085 | void _scene_cull(CullData &cull_data, InstanceCullResult &cull_result, uint64_t p_from, uint64_t p_to); |
| 1086 | _FORCE_INLINE_ bool _visibility_parent_check(const CullData &p_cull_data, const InstanceData &p_instance_data); |
| 1087 | |
| 1088 | bool _render_reflection_probe_step(Instance *p_instance, int p_step); |
| 1089 | void _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 = true, RenderInfo *r_render_info = nullptr); |
| 1090 | void render_empty_scene(const Ref<RenderSceneBuffers> &p_render_buffers, RID p_scenario, RID p_shadow_atlas); |
| 1091 | |
| 1092 | void 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, RenderingMethod::RenderInfo *r_render_info = nullptr); |
| 1093 | void update_dirty_instances(); |
| 1094 | |
| 1095 | void render_particle_colliders(); |
| 1096 | virtual void render_probes(); |
| 1097 | |
| 1098 | TypedArray<Image> bake_render_uv2(RID p_base, const TypedArray<RID> &p_material_overrides, const Size2i &p_image_size); |
| 1099 | |
| 1100 | //pass to scene render |
| 1101 | |
| 1102 | /* ENVIRONMENT API */ |
| 1103 | |
| 1104 | #ifdef PASSBASE |
| 1105 | #undef PASSBASE |
| 1106 | #endif |
| 1107 | |
| 1108 | #define PASSBASE scene_render |
| 1109 | |
| 1110 | PASS1(voxel_gi_set_quality, RS::VoxelGIQuality) |
| 1111 | |
| 1112 | /* SKY API */ |
| 1113 | |
| 1114 | PASS0R(RID, sky_allocate) |
| 1115 | PASS1(sky_initialize, RID) |
| 1116 | |
| 1117 | PASS2(sky_set_radiance_size, RID, int) |
| 1118 | PASS2(sky_set_mode, RID, RS::SkyMode) |
| 1119 | PASS2(sky_set_material, RID, RID) |
| 1120 | PASS4R(Ref<Image>, sky_bake_panorama, RID, float, bool, const Size2i &) |
| 1121 | |
| 1122 | PASS0R(RID, environment_allocate) |
| 1123 | PASS1(environment_initialize, RID) |
| 1124 | |
| 1125 | PASS1RC(bool, is_environment, RID) |
| 1126 | |
| 1127 | // Background |
| 1128 | PASS2(environment_set_background, RID, RS::EnvironmentBG) |
| 1129 | PASS2(environment_set_sky, RID, RID) |
| 1130 | PASS2(environment_set_sky_custom_fov, RID, float) |
| 1131 | PASS2(environment_set_sky_orientation, RID, const Basis &) |
| 1132 | PASS2(environment_set_bg_color, RID, const Color &) |
| 1133 | PASS3(environment_set_bg_energy, RID, float, float) |
| 1134 | PASS2(environment_set_canvas_max_layer, RID, int) |
| 1135 | PASS6(environment_set_ambient_light, RID, const Color &, RS::EnvironmentAmbientSource, float, float, RS::EnvironmentReflectionSource) |
| 1136 | |
| 1137 | PASS1RC(RS::EnvironmentBG, environment_get_background, RID) |
| 1138 | PASS1RC(RID, environment_get_sky, RID) |
| 1139 | PASS1RC(float, environment_get_sky_custom_fov, RID) |
| 1140 | PASS1RC(Basis, environment_get_sky_orientation, RID) |
| 1141 | PASS1RC(Color, environment_get_bg_color, RID) |
| 1142 | PASS1RC(float, environment_get_bg_energy_multiplier, RID) |
| 1143 | PASS1RC(float, environment_get_bg_intensity, RID) |
| 1144 | PASS1RC(int, environment_get_canvas_max_layer, RID) |
| 1145 | PASS1RC(RS::EnvironmentAmbientSource, environment_get_ambient_source, RID) |
| 1146 | PASS1RC(Color, environment_get_ambient_light, RID) |
| 1147 | PASS1RC(float, environment_get_ambient_light_energy, RID) |
| 1148 | PASS1RC(float, environment_get_ambient_sky_contribution, RID) |
| 1149 | PASS1RC(RS::EnvironmentReflectionSource, environment_get_reflection_source, RID) |
| 1150 | |
| 1151 | // Tonemap |
| 1152 | PASS4(environment_set_tonemap, RID, RS::EnvironmentToneMapper, float, float) |
| 1153 | PASS1RC(RS::EnvironmentToneMapper, environment_get_tone_mapper, RID) |
| 1154 | PASS1RC(float, environment_get_exposure, RID) |
| 1155 | PASS1RC(float, environment_get_white, RID) |
| 1156 | |
| 1157 | // Fog |
| 1158 | PASS10(environment_set_fog, RID, bool, const Color &, float, float, float, float, float, float, float) |
| 1159 | |
| 1160 | PASS1RC(bool, environment_get_fog_enabled, RID) |
| 1161 | PASS1RC(Color, environment_get_fog_light_color, RID) |
| 1162 | PASS1RC(float, environment_get_fog_light_energy, RID) |
| 1163 | PASS1RC(float, environment_get_fog_sun_scatter, RID) |
| 1164 | PASS1RC(float, environment_get_fog_density, RID) |
| 1165 | PASS1RC(float, environment_get_fog_sky_affect, RID) |
| 1166 | PASS1RC(float, environment_get_fog_height, RID) |
| 1167 | PASS1RC(float, environment_get_fog_height_density, RID) |
| 1168 | PASS1RC(float, environment_get_fog_aerial_perspective, RID) |
| 1169 | |
| 1170 | PASS2(environment_set_volumetric_fog_volume_size, int, int) |
| 1171 | PASS1(environment_set_volumetric_fog_filter_active, bool) |
| 1172 | |
| 1173 | // Volumentric Fog |
| 1174 | PASS14(environment_set_volumetric_fog, RID, bool, float, const Color &, const Color &, float, float, float, float, float, bool, float, float, float) |
| 1175 | |
| 1176 | PASS1RC(bool, environment_get_volumetric_fog_enabled, RID) |
| 1177 | PASS1RC(float, environment_get_volumetric_fog_density, RID) |
| 1178 | PASS1RC(Color, environment_get_volumetric_fog_scattering, RID) |
| 1179 | PASS1RC(Color, environment_get_volumetric_fog_emission, RID) |
| 1180 | PASS1RC(float, environment_get_volumetric_fog_emission_energy, RID) |
| 1181 | PASS1RC(float, environment_get_volumetric_fog_anisotropy, RID) |
| 1182 | PASS1RC(float, environment_get_volumetric_fog_length, RID) |
| 1183 | PASS1RC(float, environment_get_volumetric_fog_detail_spread, RID) |
| 1184 | PASS1RC(float, environment_get_volumetric_fog_gi_inject, RID) |
| 1185 | PASS1RC(float, environment_get_volumetric_fog_sky_affect, RID) |
| 1186 | PASS1RC(bool, environment_get_volumetric_fog_temporal_reprojection, RID) |
| 1187 | PASS1RC(float, environment_get_volumetric_fog_temporal_reprojection_amount, RID) |
| 1188 | PASS1RC(float, environment_get_volumetric_fog_ambient_inject, RID) |
| 1189 | |
| 1190 | // Glow |
| 1191 | PASS13(environment_set_glow, RID, bool, Vector<float>, float, float, float, float, RS::EnvironmentGlowBlendMode, float, float, float, float, RID) |
| 1192 | |
| 1193 | PASS1RC(bool, environment_get_glow_enabled, RID) |
| 1194 | PASS1RC(Vector<float>, environment_get_glow_levels, RID) |
| 1195 | PASS1RC(float, environment_get_glow_intensity, RID) |
| 1196 | PASS1RC(float, environment_get_glow_strength, RID) |
| 1197 | PASS1RC(float, environment_get_glow_bloom, RID) |
| 1198 | PASS1RC(float, environment_get_glow_mix, RID) |
| 1199 | PASS1RC(RS::EnvironmentGlowBlendMode, environment_get_glow_blend_mode, RID) |
| 1200 | PASS1RC(float, environment_get_glow_hdr_bleed_threshold, RID) |
| 1201 | PASS1RC(float, environment_get_glow_hdr_luminance_cap, RID) |
| 1202 | PASS1RC(float, environment_get_glow_hdr_bleed_scale, RID) |
| 1203 | PASS1RC(float, environment_get_glow_map_strength, RID) |
| 1204 | PASS1RC(RID, environment_get_glow_map, RID) |
| 1205 | |
| 1206 | PASS1(environment_glow_set_use_bicubic_upscale, bool) |
| 1207 | |
| 1208 | // SSR |
| 1209 | PASS6(environment_set_ssr, RID, bool, int, float, float, float) |
| 1210 | |
| 1211 | PASS1RC(bool, environment_get_ssr_enabled, RID) |
| 1212 | PASS1RC(int, environment_get_ssr_max_steps, RID) |
| 1213 | PASS1RC(float, environment_get_ssr_fade_in, RID) |
| 1214 | PASS1RC(float, environment_get_ssr_fade_out, RID) |
| 1215 | PASS1RC(float, environment_get_ssr_depth_tolerance, RID) |
| 1216 | |
| 1217 | PASS1(environment_set_ssr_roughness_quality, RS::EnvironmentSSRRoughnessQuality) |
| 1218 | |
| 1219 | // SSAO |
| 1220 | PASS10(environment_set_ssao, RID, bool, float, float, float, float, float, float, float, float) |
| 1221 | |
| 1222 | PASS1RC(bool, environment_get_ssao_enabled, RID) |
| 1223 | PASS1RC(float, environment_get_ssao_radius, RID) |
| 1224 | PASS1RC(float, environment_get_ssao_intensity, RID) |
| 1225 | PASS1RC(float, environment_get_ssao_power, RID) |
| 1226 | PASS1RC(float, environment_get_ssao_detail, RID) |
| 1227 | PASS1RC(float, environment_get_ssao_horizon, RID) |
| 1228 | PASS1RC(float, environment_get_ssao_sharpness, RID) |
| 1229 | PASS1RC(float, environment_get_ssao_direct_light_affect, RID) |
| 1230 | PASS1RC(float, environment_get_ssao_ao_channel_affect, RID) |
| 1231 | |
| 1232 | PASS6(environment_set_ssao_quality, RS::EnvironmentSSAOQuality, bool, float, int, float, float) |
| 1233 | |
| 1234 | // SSIL |
| 1235 | PASS6(environment_set_ssil, RID, bool, float, float, float, float) |
| 1236 | |
| 1237 | PASS1RC(bool, environment_get_ssil_enabled, RID) |
| 1238 | PASS1RC(float, environment_get_ssil_radius, RID) |
| 1239 | PASS1RC(float, environment_get_ssil_intensity, RID) |
| 1240 | PASS1RC(float, environment_get_ssil_sharpness, RID) |
| 1241 | PASS1RC(float, environment_get_ssil_normal_rejection, RID) |
| 1242 | |
| 1243 | PASS6(environment_set_ssil_quality, RS::EnvironmentSSILQuality, bool, float, int, float, float) |
| 1244 | |
| 1245 | // SDFGI |
| 1246 | |
| 1247 | PASS11(environment_set_sdfgi, RID, bool, int, float, RS::EnvironmentSDFGIYScale, bool, float, bool, float, float, float) |
| 1248 | |
| 1249 | PASS1RC(bool, environment_get_sdfgi_enabled, RID) |
| 1250 | PASS1RC(int, environment_get_sdfgi_cascades, RID) |
| 1251 | PASS1RC(float, environment_get_sdfgi_min_cell_size, RID) |
| 1252 | PASS1RC(bool, environment_get_sdfgi_use_occlusion, RID) |
| 1253 | PASS1RC(float, environment_get_sdfgi_bounce_feedback, RID) |
| 1254 | PASS1RC(bool, environment_get_sdfgi_read_sky_light, RID) |
| 1255 | PASS1RC(float, environment_get_sdfgi_energy, RID) |
| 1256 | PASS1RC(float, environment_get_sdfgi_normal_bias, RID) |
| 1257 | PASS1RC(float, environment_get_sdfgi_probe_bias, RID) |
| 1258 | PASS1RC(RS::EnvironmentSDFGIYScale, environment_get_sdfgi_y_scale, RID) |
| 1259 | |
| 1260 | PASS1(environment_set_sdfgi_ray_count, RS::EnvironmentSDFGIRayCount) |
| 1261 | PASS1(environment_set_sdfgi_frames_to_converge, RS::EnvironmentSDFGIFramesToConverge) |
| 1262 | PASS1(environment_set_sdfgi_frames_to_update_light, RS::EnvironmentSDFGIFramesToUpdateLight) |
| 1263 | |
| 1264 | // Adjustment |
| 1265 | PASS7(environment_set_adjustment, RID, bool, float, float, float, bool, RID) |
| 1266 | |
| 1267 | PASS1RC(bool, environment_get_adjustments_enabled, RID) |
| 1268 | PASS1RC(float, environment_get_adjustments_brightness, RID) |
| 1269 | PASS1RC(float, environment_get_adjustments_contrast, RID) |
| 1270 | PASS1RC(float, environment_get_adjustments_saturation, RID) |
| 1271 | PASS1RC(bool, environment_get_use_1d_color_correction, RID) |
| 1272 | PASS1RC(RID, environment_get_color_correction, RID) |
| 1273 | |
| 1274 | PASS3R(Ref<Image>, environment_bake_panorama, RID, bool, const Size2i &) |
| 1275 | |
| 1276 | PASS3(screen_space_roughness_limiter_set_active, bool, float, float) |
| 1277 | PASS1(sub_surface_scattering_set_quality, RS::SubSurfaceScatteringQuality) |
| 1278 | PASS2(sub_surface_scattering_set_scale, float, float) |
| 1279 | |
| 1280 | PASS1(positional_soft_shadow_filter_set_quality, RS::ShadowQuality) |
| 1281 | PASS1(directional_soft_shadow_filter_set_quality, RS::ShadowQuality) |
| 1282 | |
| 1283 | PASS2(sdfgi_set_debug_probe_select, const Vector3 &, const Vector3 &) |
| 1284 | |
| 1285 | /* Render Buffers */ |
| 1286 | |
| 1287 | PASS0R(Ref<RenderSceneBuffers>, render_buffers_create) |
| 1288 | PASS1(gi_set_use_half_resolution, bool) |
| 1289 | |
| 1290 | /* Misc */ |
| 1291 | PASS1(set_debug_draw_mode, RS::ViewportDebugDraw) |
| 1292 | |
| 1293 | PASS1(decals_set_filter, RS::DecalFilter) |
| 1294 | PASS1(light_projectors_set_filter, RS::LightProjectorFilter) |
| 1295 | |
| 1296 | virtual void update(); |
| 1297 | |
| 1298 | bool free(RID p_rid); |
| 1299 | |
| 1300 | void set_scene_render(RendererSceneRender *p_scene_render); |
| 1301 | |
| 1302 | virtual void update_visibility_notifiers(); |
| 1303 | |
| 1304 | RendererSceneCull(); |
| 1305 | virtual ~RendererSceneCull(); |
| 1306 | }; |
| 1307 | |
| 1308 | #endif // RENDERER_SCENE_CULL_H |
| 1309 | |