Overhaul the cull mask internals for Lights, Decals, and Particle Colliders

Properly pair and unpair instances based on cull mask to avoid any unnecessary processing and to ensure that changing the cull_mask and layer_mask actually updates culling behavior
This commit is contained in:
clayjohn 2025-02-03 23:02:20 -08:00
parent 8f78e7510d
commit 305216f558
13 changed files with 67 additions and 14 deletions

View file

@ -508,7 +508,8 @@ public:
case Dependency::DEPENDENCY_CHANGED_REFLECTION_PROBE: {
singleton->_instance_queue_update(instance, true, true);
} break;
case Dependency::DEPENDENCY_CHANGED_LIGHT_SOFT_SHADOW_AND_PROJECTOR: {
case Dependency::DEPENDENCY_CHANGED_LIGHT_SOFT_SHADOW_AND_PROJECTOR:
case Dependency::DEPENDENCY_CHANGED_CULL_MASK: {
//requires repairing
if (instance->indexer_id.is_valid()) {
singleton->_unpair_instance(instance);
@ -655,6 +656,7 @@ public:
struct InstanceDecalData : public InstanceBaseData {
Instance *owner = nullptr;
RID instance;
uint32_t cull_mask = 0xFFFFFFFF;
HashSet<Instance *> geometries;
@ -666,6 +668,7 @@ public:
struct InstanceParticlesCollisionData : public InstanceBaseData {
RID instance;
uint32_t cull_mask = 0xFFFFFFFF;
};
struct InstanceFogVolumeData : public InstanceBaseData {
@ -699,6 +702,7 @@ public:
RS::LightBakeMode bake_mode;
uint32_t max_sdfgi_cascade = 2;
uint32_t cull_mask = 0xFFFFFFFF;
private:
// Instead of a single dirty flag, we maintain a count
@ -817,12 +821,11 @@ public:
DynamicBVH *bvh2 = nullptr; //some may need to cull in two
uint32_t pair_mask;
uint64_t pair_pass;
uint32_t cull_mask = 0xFFFFFFFF; // Needed for decals and lights in the mobile and compatibility renderers.
_FORCE_INLINE_ bool operator()(void *p_data) {
Instance *p_instance = (Instance *)p_data;
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)) {
if (instance != p_instance && instance->transformed_aabb.intersects(p_instance->transformed_aabb) && (pair_mask & (1 << p_instance->base_type))) {
//test is more coarse in indexer
p_instance->pair_check = pair_pass;
InstancePair *pair = pair_allocator->alloc();