|
@@ -109,6 +109,20 @@ bool RendererSceneCull::is_camera(RID p_camera) const {
|
|
return camera_owner.owns(p_camera);
|
|
return camera_owner.owns(p_camera);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+/* OCCLUDER API */
|
|
|
|
+
|
|
|
|
+RID RendererSceneCull::occluder_allocate() {
|
|
|
|
+ return RendererSceneOcclusionCull::get_singleton()->occluder_allocate();
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void RendererSceneCull::occluder_initialize(RID p_rid) {
|
|
|
|
+ RendererSceneOcclusionCull::get_singleton()->occluder_initialize(p_rid);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void RendererSceneCull::occluder_set_mesh(RID p_occluder, const PackedVector3Array &p_vertices, const PackedInt32Array &p_indices) {
|
|
|
|
+ RendererSceneOcclusionCull::get_singleton()->occluder_set_mesh(p_occluder, p_vertices, p_indices);
|
|
|
|
+}
|
|
|
|
+
|
|
/* SCENARIO API */
|
|
/* SCENARIO API */
|
|
|
|
|
|
void RendererSceneCull::_instance_pair(Instance *p_A, Instance *p_B) {
|
|
void RendererSceneCull::_instance_pair(Instance *p_A, Instance *p_B) {
|
|
@@ -310,6 +324,8 @@ void RendererSceneCull::scenario_initialize(RID p_rid) {
|
|
scenario->instance_aabbs.set_page_pool(&instance_aabb_page_pool);
|
|
scenario->instance_aabbs.set_page_pool(&instance_aabb_page_pool);
|
|
scenario->instance_data.set_page_pool(&instance_data_page_pool);
|
|
scenario->instance_data.set_page_pool(&instance_data_page_pool);
|
|
|
|
|
|
|
|
+ RendererSceneOcclusionCull::get_singleton()->add_scenario(p_rid);
|
|
|
|
+
|
|
scenario_owner.initialize_rid(p_rid, scenario);
|
|
scenario_owner.initialize_rid(p_rid, scenario);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -497,6 +513,11 @@ void RendererSceneCull::instance_set_base(RID p_instance, RID p_base) {
|
|
scene_render->free(gi_probe->probe_instance);
|
|
scene_render->free(gi_probe->probe_instance);
|
|
|
|
|
|
} break;
|
|
} break;
|
|
|
|
+ case RS::INSTANCE_OCCLUDER: {
|
|
|
|
+ if (scenario && instance->visible) {
|
|
|
|
+ RendererSceneOcclusionCull::get_singleton()->scenario_remove_instance(instance->scenario->self, p_instance);
|
|
|
|
+ }
|
|
|
|
+ } break;
|
|
default: {
|
|
default: {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -514,6 +535,11 @@ void RendererSceneCull::instance_set_base(RID p_instance, RID p_base) {
|
|
|
|
|
|
if (p_base.is_valid()) {
|
|
if (p_base.is_valid()) {
|
|
instance->base_type = RSG::storage->get_base_type(p_base);
|
|
instance->base_type = RSG::storage->get_base_type(p_base);
|
|
|
|
+
|
|
|
|
+ if (instance->base_type == RS::INSTANCE_NONE && RendererSceneOcclusionCull::get_singleton()->is_occluder(p_base)) {
|
|
|
|
+ instance->base_type = RS::INSTANCE_OCCLUDER;
|
|
|
|
+ }
|
|
|
|
+
|
|
ERR_FAIL_COND(instance->base_type == RS::INSTANCE_NONE);
|
|
ERR_FAIL_COND(instance->base_type == RS::INSTANCE_NONE);
|
|
|
|
|
|
switch (instance->base_type) {
|
|
switch (instance->base_type) {
|
|
@@ -588,6 +614,11 @@ void RendererSceneCull::instance_set_base(RID p_instance, RID p_base) {
|
|
gi_probe->probe_instance = scene_render->gi_probe_instance_create(p_base);
|
|
gi_probe->probe_instance = scene_render->gi_probe_instance_create(p_base);
|
|
|
|
|
|
} break;
|
|
} break;
|
|
|
|
+ case RS::INSTANCE_OCCLUDER: {
|
|
|
|
+ if (scenario) {
|
|
|
|
+ RendererSceneOcclusionCull::get_singleton()->scenario_set_instance(scenario->self, p_instance, p_base, instance->transform, instance->visible);
|
|
|
|
+ }
|
|
|
|
+ } break;
|
|
default: {
|
|
default: {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -655,6 +686,11 @@ void RendererSceneCull::instance_set_scenario(RID p_instance, RID p_scenario) {
|
|
gi_probe_update_list.remove(&gi_probe->update_element);
|
|
gi_probe_update_list.remove(&gi_probe->update_element);
|
|
}
|
|
}
|
|
} break;
|
|
} break;
|
|
|
|
+ case RS::INSTANCE_OCCLUDER: {
|
|
|
|
+ if (instance->visible) {
|
|
|
|
+ RendererSceneOcclusionCull::get_singleton()->scenario_remove_instance(instance->scenario->self, p_instance);
|
|
|
|
+ }
|
|
|
|
+ } break;
|
|
default: {
|
|
default: {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -684,6 +720,9 @@ void RendererSceneCull::instance_set_scenario(RID p_instance, RID p_scenario) {
|
|
gi_probe_update_list.add(&gi_probe->update_element);
|
|
gi_probe_update_list.add(&gi_probe->update_element);
|
|
}
|
|
}
|
|
} break;
|
|
} break;
|
|
|
|
+ case RS::INSTANCE_OCCLUDER: {
|
|
|
|
+ RendererSceneOcclusionCull::get_singleton()->scenario_set_instance(scenario->self, p_instance, instance->base, instance->transform, instance->visible);
|
|
|
|
+ } break;
|
|
default: {
|
|
default: {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -801,6 +840,12 @@ void RendererSceneCull::instance_set_visible(RID p_instance, bool p_visible) {
|
|
InstanceParticlesCollisionData *collision = static_cast<InstanceParticlesCollisionData *>(instance->base_data);
|
|
InstanceParticlesCollisionData *collision = static_cast<InstanceParticlesCollisionData *>(instance->base_data);
|
|
RSG::storage->particles_collision_instance_set_active(collision->instance, p_visible);
|
|
RSG::storage->particles_collision_instance_set_active(collision->instance, p_visible);
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ if (instance->base_type == RS::INSTANCE_OCCLUDER) {
|
|
|
|
+ if (instance->scenario) {
|
|
|
|
+ RendererSceneOcclusionCull::get_singleton()->scenario_set_instance(instance->scenario->self, p_instance, instance->base, instance->transform, p_visible);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
inline bool is_geometry_instance(RenderingServer::InstanceType p_type) {
|
|
inline bool is_geometry_instance(RenderingServer::InstanceType p_type) {
|
|
@@ -998,6 +1043,18 @@ void RendererSceneCull::instance_geometry_set_flag(RID p_instance, RS::InstanceF
|
|
}
|
|
}
|
|
|
|
|
|
} break;
|
|
} break;
|
|
|
|
+ case RS::INSTANCE_FLAG_IGNORE_OCCLUSION_CULLING: {
|
|
|
|
+ instance->ignore_occlusion_culling = p_enabled;
|
|
|
|
+
|
|
|
|
+ if (instance->scenario && instance->array_index >= 0) {
|
|
|
|
+ InstanceData &idata = instance->scenario->instance_data[instance->array_index];
|
|
|
|
+ if (instance->ignore_occlusion_culling) {
|
|
|
|
+ idata.flags |= InstanceData::FLAG_IGNORE_OCCLUSION_CULLING;
|
|
|
|
+ } else {
|
|
|
|
+ idata.flags &= ~uint32_t(InstanceData::FLAG_IGNORE_OCCLUSION_CULLING);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ } break;
|
|
default: {
|
|
default: {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -1210,6 +1267,10 @@ void RendererSceneCull::_update_instance(Instance *p_instance) {
|
|
heightfield_particle_colliders_update_list.insert(p_instance);
|
|
heightfield_particle_colliders_update_list.insert(p_instance);
|
|
}
|
|
}
|
|
RSG::storage->particles_collision_instance_set_transform(collision->instance, p_instance->transform);
|
|
RSG::storage->particles_collision_instance_set_transform(collision->instance, p_instance->transform);
|
|
|
|
+ } else if (p_instance->base_type == RS::INSTANCE_OCCLUDER) {
|
|
|
|
+ if (p_instance->scenario) {
|
|
|
|
+ RendererSceneOcclusionCull::get_singleton()->scenario_set_instance(p_instance->scenario->self, p_instance->self, p_instance->base, p_instance->transform, p_instance->visible);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
if (p_instance->aabb.has_no_surface()) {
|
|
if (p_instance->aabb.has_no_surface()) {
|
|
@@ -1337,6 +1398,9 @@ void RendererSceneCull::_update_instance(Instance *p_instance) {
|
|
if (p_instance->mesh_instance.is_valid()) {
|
|
if (p_instance->mesh_instance.is_valid()) {
|
|
idata.flags |= InstanceData::FLAG_USES_MESH_INSTANCE;
|
|
idata.flags |= InstanceData::FLAG_USES_MESH_INSTANCE;
|
|
}
|
|
}
|
|
|
|
+ if (p_instance->ignore_occlusion_culling) {
|
|
|
|
+ idata.flags |= InstanceData::FLAG_IGNORE_OCCLUSION_CULLING;
|
|
|
|
+ }
|
|
|
|
|
|
p_instance->scenario->instance_data.push_back(idata);
|
|
p_instance->scenario->instance_data.push_back(idata);
|
|
p_instance->scenario->instance_aabbs.push_back(InstanceBounds(p_instance->transformed_aabb));
|
|
p_instance->scenario->instance_aabbs.push_back(InstanceBounds(p_instance->transformed_aabb));
|
|
@@ -2119,7 +2183,7 @@ bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, cons
|
|
return animated_material_found;
|
|
return animated_material_found;
|
|
}
|
|
}
|
|
|
|
|
|
-void RendererSceneCull::render_camera(RID p_render_buffers, RID p_camera, RID p_scenario, Size2 p_viewport_size, float p_screen_lod_threshold, RID p_shadow_atlas) {
|
|
|
|
|
|
+void RendererSceneCull::render_camera(RID p_render_buffers, RID p_camera, RID p_scenario, RID p_viewport, Size2 p_viewport_size, float p_screen_lod_threshold, RID p_shadow_atlas) {
|
|
// render to mono camera
|
|
// render to mono camera
|
|
#ifndef _3D_DISABLED
|
|
#ifndef _3D_DISABLED
|
|
|
|
|
|
@@ -2164,11 +2228,14 @@ void RendererSceneCull::render_camera(RID p_render_buffers, RID p_camera, RID p_
|
|
|
|
|
|
RID environment = _render_get_environment(p_camera, p_scenario);
|
|
RID environment = _render_get_environment(p_camera, p_scenario);
|
|
|
|
|
|
- _render_scene(camera->transform, camera_matrix, ortho, camera->vaspect, p_render_buffers, environment, camera->effects, camera->visible_layers, p_scenario, p_shadow_atlas, RID(), -1, p_screen_lod_threshold);
|
|
|
|
|
|
+ RENDER_TIMESTAMP("Update occlusion buffer")
|
|
|
|
+ RendererSceneOcclusionCull::get_singleton()->buffer_update(p_viewport, camera->transform, camera_matrix, ortho, RendererThreadPool::singleton->thread_work_pool);
|
|
|
|
+
|
|
|
|
+ _render_scene(camera->transform, camera_matrix, ortho, camera->vaspect, p_render_buffers, environment, camera->effects, camera->visible_layers, p_scenario, p_viewport, p_shadow_atlas, RID(), -1, p_screen_lod_threshold);
|
|
#endif
|
|
#endif
|
|
}
|
|
}
|
|
|
|
|
|
-void RendererSceneCull::render_camera(RID p_render_buffers, Ref<XRInterface> &p_interface, XRInterface::Eyes p_eye, RID p_camera, RID p_scenario, Size2 p_viewport_size, float p_screen_lod_threshold, RID p_shadow_atlas) {
|
|
|
|
|
|
+void RendererSceneCull::render_camera(RID p_render_buffers, Ref<XRInterface> &p_interface, XRInterface::Eyes p_eye, RID p_camera, RID p_scenario, RID p_viewport, Size2 p_viewport_size, float p_screen_lod_threshold, RID p_shadow_atlas) {
|
|
// render for AR/VR interface
|
|
// render for AR/VR interface
|
|
#if 0
|
|
#if 0
|
|
Camera *camera = camera_owner.getornull(p_camera);
|
|
Camera *camera = camera_owner.getornull(p_camera);
|
|
@@ -2253,7 +2320,7 @@ void RendererSceneCull::render_camera(RID p_render_buffers, Ref<XRInterface> &p_
|
|
#endif
|
|
#endif
|
|
};
|
|
};
|
|
|
|
|
|
-void RendererSceneCull::_frustum_cull_threaded(uint32_t p_thread, FrustumCullData *cull_data) {
|
|
|
|
|
|
+void RendererSceneCull::_frustum_cull_threaded(uint32_t p_thread, CullData *cull_data) {
|
|
uint32_t cull_total = cull_data->scenario->instance_data.size();
|
|
uint32_t cull_total = cull_data->scenario->instance_data.size();
|
|
uint32_t total_threads = RendererThreadPool::singleton->thread_work_pool.get_thread_count();
|
|
uint32_t total_threads = RendererThreadPool::singleton->thread_work_pool.get_thread_count();
|
|
uint32_t cull_from = p_thread * cull_total / total_threads;
|
|
uint32_t cull_from = p_thread * cull_total / total_threads;
|
|
@@ -2262,7 +2329,7 @@ void RendererSceneCull::_frustum_cull_threaded(uint32_t p_thread, FrustumCullDat
|
|
_frustum_cull(*cull_data, frustum_cull_result_threads[p_thread], cull_from, cull_to);
|
|
_frustum_cull(*cull_data, frustum_cull_result_threads[p_thread], cull_from, cull_to);
|
|
}
|
|
}
|
|
|
|
|
|
-void RendererSceneCull::_frustum_cull(FrustumCullData &cull_data, FrustumCullResult &cull_result, uint64_t p_from, uint64_t p_to) {
|
|
|
|
|
|
+void RendererSceneCull::_frustum_cull(CullData &cull_data, FrustumCullResult &cull_result, uint64_t p_from, uint64_t p_to) {
|
|
uint64_t frame_number = RSG::rasterizer->get_frame_number();
|
|
uint64_t frame_number = RSG::rasterizer->get_frame_number();
|
|
float lightmap_probe_update_speed = RSG::storage->lightmap_get_probe_capture_update_speed() * RSG::rasterizer->get_frame_delta_time();
|
|
float lightmap_probe_update_speed = RSG::storage->lightmap_get_probe_capture_update_speed() * RSG::rasterizer->get_frame_delta_time();
|
|
|
|
|
|
@@ -2271,10 +2338,14 @@ void RendererSceneCull::_frustum_cull(FrustumCullData &cull_data, FrustumCullRes
|
|
|
|
|
|
RID instance_pair_buffer[MAX_INSTANCE_PAIRS];
|
|
RID instance_pair_buffer[MAX_INSTANCE_PAIRS];
|
|
|
|
|
|
|
|
+ Transform inv_cam_transform = cull_data.cam_transform.inverse();
|
|
|
|
+ float z_near = cull_data.camera_matrix->get_z_near();
|
|
|
|
+
|
|
for (uint64_t i = p_from; i < p_to; i++) {
|
|
for (uint64_t i = p_from; i < p_to; i++) {
|
|
bool mesh_visible = false;
|
|
bool mesh_visible = false;
|
|
|
|
|
|
- if (cull_data.scenario->instance_aabbs[i].in_frustum(cull_data.cull->frustum)) {
|
|
|
|
|
|
+ if (cull_data.scenario->instance_aabbs[i].in_frustum(cull_data.cull->frustum) && (cull_data.occlusion_buffer == nullptr || cull_data.scenario->instance_data[i].flags & InstanceData::FLAG_IGNORE_OCCLUSION_CULLING ||
|
|
|
|
+ !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))) {
|
|
InstanceData &idata = cull_data.scenario->instance_data[i];
|
|
InstanceData &idata = cull_data.scenario->instance_data[i];
|
|
uint32_t base_type = idata.flags & InstanceData::FLAG_BASE_TYPE_MASK;
|
|
uint32_t base_type = idata.flags & InstanceData::FLAG_BASE_TYPE_MASK;
|
|
|
|
|
|
@@ -2469,7 +2540,7 @@ void RendererSceneCull::_frustum_cull(FrustumCullData &cull_data, FrustumCullRes
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-void RendererSceneCull::_render_scene(const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect, RID p_render_buffers, RID p_environment, RID p_force_camera_effects, uint32_t p_visible_layers, RID p_scenario, RID p_shadow_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold, bool p_using_shadows) {
|
|
|
|
|
|
+void RendererSceneCull::_render_scene(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect, RID p_render_buffers, RID p_environment, RID p_force_camera_effects, 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_lod_threshold, bool p_using_shadows) {
|
|
// Note, in stereo rendering:
|
|
// Note, in stereo rendering:
|
|
// - p_cam_transform will be a transform in the middle of our two eyes
|
|
// - p_cam_transform will be a transform in the middle of our two eyes
|
|
// - p_cam_projection is a wider frustrum that encompasses both eyes
|
|
// - p_cam_projection is a wider frustrum that encompasses both eyes
|
|
@@ -2566,7 +2637,7 @@ void RendererSceneCull::_render_scene(const Transform p_cam_transform, const Cam
|
|
uint64_t cull_from = 0;
|
|
uint64_t cull_from = 0;
|
|
uint64_t cull_to = scenario->instance_data.size();
|
|
uint64_t cull_to = scenario->instance_data.size();
|
|
|
|
|
|
- FrustumCullData cull_data;
|
|
|
|
|
|
+ CullData cull_data;
|
|
|
|
|
|
//prepare for eventual thread usage
|
|
//prepare for eventual thread usage
|
|
cull_data.cull = &cull;
|
|
cull_data.cull = &cull;
|
|
@@ -2575,6 +2646,8 @@ void RendererSceneCull::_render_scene(const Transform p_cam_transform, const Cam
|
|
cull_data.cam_transform = p_cam_transform;
|
|
cull_data.cam_transform = p_cam_transform;
|
|
cull_data.visible_layers = p_visible_layers;
|
|
cull_data.visible_layers = p_visible_layers;
|
|
cull_data.render_reflection_probe = render_reflection_probe;
|
|
cull_data.render_reflection_probe = render_reflection_probe;
|
|
|
|
+ cull_data.occlusion_buffer = RendererSceneOcclusionCull::get_singleton()->buffer_get_ptr(p_viewport);
|
|
|
|
+ cull_data.camera_matrix = &p_cam_projection;
|
|
//#define DEBUG_CULL_TIME
|
|
//#define DEBUG_CULL_TIME
|
|
#ifdef DEBUG_CULL_TIME
|
|
#ifdef DEBUG_CULL_TIME
|
|
uint64_t time_from = OS::get_singleton()->get_ticks_usec();
|
|
uint64_t time_from = OS::get_singleton()->get_ticks_usec();
|
|
@@ -2781,8 +2854,13 @@ void RendererSceneCull::_render_scene(const Transform p_cam_transform, const Cam
|
|
}
|
|
}
|
|
/* PROCESS GEOMETRY AND DRAW SCENE */
|
|
/* PROCESS GEOMETRY AND DRAW SCENE */
|
|
|
|
|
|
|
|
+ RID occluders_tex;
|
|
|
|
+ if (p_viewport.is_valid()) {
|
|
|
|
+ occluders_tex = RSG::viewport->viewport_get_occluder_debug_texture(p_viewport);
|
|
|
|
+ }
|
|
|
|
+
|
|
RENDER_TIMESTAMP("Render Scene ");
|
|
RENDER_TIMESTAMP("Render Scene ");
|
|
- scene_render->render_scene(p_render_buffers, p_cam_transform, p_cam_projection, p_cam_orthogonal, frustum_cull_result.geometry_instances, frustum_cull_result.light_instances, frustum_cull_result.reflections, frustum_cull_result.gi_probes, frustum_cull_result.decals, frustum_cull_result.lightmaps, p_environment, camera_effects, p_shadow_atlas, p_reflection_probe.is_valid() ? RID() : scenario->reflection_atlas, p_reflection_probe, p_reflection_probe_pass, p_screen_lod_threshold, render_shadow_data, max_shadows_used, render_sdfgi_data, cull.sdfgi.region_count, &sdfgi_update_data);
|
|
|
|
|
|
+ scene_render->render_scene(p_render_buffers, p_cam_transform, p_cam_projection, p_cam_orthogonal, frustum_cull_result.geometry_instances, frustum_cull_result.light_instances, frustum_cull_result.reflections, frustum_cull_result.gi_probes, frustum_cull_result.decals, frustum_cull_result.lightmaps, p_environment, camera_effects, p_shadow_atlas, occluders_tex, p_reflection_probe.is_valid() ? RID() : scenario->reflection_atlas, p_reflection_probe, p_reflection_probe_pass, p_screen_lod_threshold, render_shadow_data, max_shadows_used, render_sdfgi_data, cull.sdfgi.region_count, &sdfgi_update_data);
|
|
|
|
|
|
for (uint32_t i = 0; i < max_shadows_used; i++) {
|
|
for (uint32_t i = 0; i < max_shadows_used; i++) {
|
|
render_shadow_data[i].instances.clear();
|
|
render_shadow_data[i].instances.clear();
|
|
@@ -2829,7 +2907,7 @@ void RendererSceneCull::render_empty_scene(RID p_render_buffers, RID p_scenario,
|
|
environment = scenario->fallback_environment;
|
|
environment = scenario->fallback_environment;
|
|
}
|
|
}
|
|
RENDER_TIMESTAMP("Render Empty Scene ");
|
|
RENDER_TIMESTAMP("Render Empty Scene ");
|
|
- scene_render->render_scene(p_render_buffers, Transform(), CameraMatrix(), true, PagedArray<RendererSceneRender::GeometryInstance *>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), RID(), RID(), p_shadow_atlas, scenario->reflection_atlas, RID(), 0, 0, nullptr, 0, nullptr, 0, nullptr);
|
|
|
|
|
|
+ scene_render->render_scene(p_render_buffers, Transform(), CameraMatrix(), true, PagedArray<RendererSceneRender::GeometryInstance *>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), RID(), RID(), p_shadow_atlas, RID(), scenario->reflection_atlas, RID(), 0, 0, nullptr, 0, nullptr, 0, nullptr);
|
|
#endif
|
|
#endif
|
|
}
|
|
}
|
|
|
|
|
|
@@ -2899,7 +2977,7 @@ bool RendererSceneCull::_render_reflection_probe_step(Instance *p_instance, int
|
|
}
|
|
}
|
|
|
|
|
|
RENDER_TIMESTAMP("Render Reflection Probe, Step " + itos(p_step));
|
|
RENDER_TIMESTAMP("Render Reflection Probe, Step " + itos(p_step));
|
|
- _render_scene(xform, cm, false, false, RID(), environment, RID(), RSG::storage->reflection_probe_get_cull_mask(p_instance->base), p_instance->scenario->self, shadow_atlas, reflection_probe->instance, p_step, lod_threshold, use_shadows);
|
|
|
|
|
|
+ _render_scene(xform, cm, false, false, RID(), environment, RID(), RSG::storage->reflection_probe_get_cull_mask(p_instance->base), p_instance->scenario->self, RID(), shadow_atlas, reflection_probe->instance, p_step, lod_threshold, use_shadows);
|
|
|
|
|
|
} else {
|
|
} else {
|
|
//do roughness postprocess step until it believes it's done
|
|
//do roughness postprocess step until it believes it's done
|
|
@@ -3473,8 +3551,11 @@ bool RendererSceneCull::free(RID p_rid) {
|
|
scene_render->free(scenario->reflection_probe_shadow_atlas);
|
|
scene_render->free(scenario->reflection_probe_shadow_atlas);
|
|
scene_render->free(scenario->reflection_atlas);
|
|
scene_render->free(scenario->reflection_atlas);
|
|
scenario_owner.free(p_rid);
|
|
scenario_owner.free(p_rid);
|
|
|
|
+ RendererSceneOcclusionCull::get_singleton()->remove_scenario(p_rid);
|
|
memdelete(scenario);
|
|
memdelete(scenario);
|
|
|
|
|
|
|
|
+ } else if (RendererSceneOcclusionCull::get_singleton()->is_occluder(p_rid)) {
|
|
|
|
+ RendererSceneOcclusionCull::get_singleton()->free_occluder(p_rid);
|
|
} else if (instance_owner.owns(p_rid)) {
|
|
} else if (instance_owner.owns(p_rid)) {
|
|
// delete the instance
|
|
// delete the instance
|
|
|
|
|
|
@@ -3543,6 +3624,8 @@ RendererSceneCull::RendererSceneCull() {
|
|
indexer_update_iterations = GLOBAL_GET("rendering/limits/spatial_indexer/update_iterations_per_frame");
|
|
indexer_update_iterations = GLOBAL_GET("rendering/limits/spatial_indexer/update_iterations_per_frame");
|
|
thread_cull_threshold = GLOBAL_GET("rendering/limits/spatial_indexer/threaded_cull_minimum_instances");
|
|
thread_cull_threshold = GLOBAL_GET("rendering/limits/spatial_indexer/threaded_cull_minimum_instances");
|
|
thread_cull_threshold = MAX(thread_cull_threshold, (uint32_t)RendererThreadPool::singleton->thread_work_pool.get_thread_count()); //make sure there is at least one thread per CPU
|
|
thread_cull_threshold = MAX(thread_cull_threshold, (uint32_t)RendererThreadPool::singleton->thread_work_pool.get_thread_count()); //make sure there is at least one thread per CPU
|
|
|
|
+
|
|
|
|
+ dummy_occlusion_culling = memnew(RendererSceneOcclusionCull);
|
|
}
|
|
}
|
|
|
|
|
|
RendererSceneCull::~RendererSceneCull() {
|
|
RendererSceneCull::~RendererSceneCull() {
|
|
@@ -3561,4 +3644,8 @@ RendererSceneCull::~RendererSceneCull() {
|
|
frustum_cull_result_threads[i].reset();
|
|
frustum_cull_result_threads[i].reset();
|
|
}
|
|
}
|
|
frustum_cull_result_threads.clear();
|
|
frustum_cull_result_threads.clear();
|
|
|
|
+
|
|
|
|
+ if (dummy_occlusion_culling) {
|
|
|
|
+ memdelete(dummy_occlusion_culling);
|
|
|
|
+ }
|
|
}
|
|
}
|