Implement cull_mask for decals and lights in mobile and compatibility backends

This commit is contained in:
clayjohn 2023-02-06 12:12:47 -08:00
parent 5eb2011423
commit 56450fb179
13 changed files with 35 additions and 16 deletions

View file

@ -311,6 +311,13 @@ uint64_t LightStorage::light_get_version(RID p_light) const {
return light->version;
}
uint32_t LightStorage::light_get_cull_mask(RID p_light) const {
const Light *light = light_owner.get_or_null(p_light);
ERR_FAIL_COND_V(!light, 0);
return light->cull_mask;
}
AABB LightStorage::light_get_aabb(RID p_light) const {
const Light *light = light_owner.get_or_null(p_light);
ERR_FAIL_COND_V(!light, AABB());

View file

@ -239,13 +239,6 @@ public:
return light->color;
}
_FORCE_INLINE_ uint32_t light_get_cull_mask(RID p_light) {
const Light *light = light_owner.get_or_null(p_light);
ERR_FAIL_COND_V(!light, 0);
return light->cull_mask;
}
_FORCE_INLINE_ bool light_is_distance_fade_enabled(RID p_light) {
const Light *light = light_owner.get_or_null(p_light);
return light->distance_fade;
@ -297,6 +290,7 @@ public:
virtual RS::LightBakeMode light_get_bake_mode(RID p_light) override;
virtual uint32_t light_get_max_sdfgi_cascade(RID p_light) override { return 0; }
virtual uint64_t light_get_version(RID p_light) const override;
virtual uint32_t light_get_cull_mask(RID p_light) const override;
/* LIGHT INSTANCE API */

View file

@ -585,6 +585,7 @@ public:
virtual void decal_set_normal_fade(RID p_decal, float p_fade) override;
virtual AABB decal_get_aabb(RID p_decal) const override;
virtual uint32_t decal_get_cull_mask(RID p_decal) const override { return 0; }
virtual void texture_add_to_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) override {}
virtual void texture_remove_from_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) override {}

View file

@ -80,6 +80,7 @@ public:
virtual RS::LightBakeMode light_get_bake_mode(RID p_light) override { return RS::LIGHT_BAKE_DISABLED; }
virtual uint32_t light_get_max_sdfgi_cascade(RID p_light) override { return 0; }
virtual uint64_t light_get_version(RID p_light) const override { return 0; }
virtual uint32_t light_get_cull_mask(RID p_light) const override { return 0; }
/* LIGHT INSTANCE API */

View file

@ -145,6 +145,7 @@ public:
virtual void decal_set_normal_fade(RID p_decal, float p_fade) override {}
virtual AABB decal_get_aabb(RID p_decal) const override { return AABB(); }
virtual uint32_t decal_get_cull_mask(RID p_decal) const override { return 0; }
virtual void texture_add_to_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) override {}
virtual void texture_remove_from_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) override {}

View file

@ -389,6 +389,13 @@ uint64_t LightStorage::light_get_version(RID p_light) const {
return light->version;
}
uint32_t LightStorage::light_get_cull_mask(RID p_light) const {
const Light *light = light_owner.get_or_null(p_light);
ERR_FAIL_COND_V(!light, 0);
return light->cull_mask;
}
AABB LightStorage::light_get_aabb(RID p_light) const {
const Light *light = light_owner.get_or_null(p_light);
ERR_FAIL_COND_V(!light, AABB());

View file

@ -517,13 +517,6 @@ public:
return light->color;
}
_FORCE_INLINE_ uint32_t light_get_cull_mask(RID p_light) {
const Light *light = light_owner.get_or_null(p_light);
ERR_FAIL_COND_V(!light, 0);
return light->cull_mask;
}
_FORCE_INLINE_ bool light_is_distance_fade_enabled(RID p_light) {
const Light *light = light_owner.get_or_null(p_light);
return light->distance_fade;
@ -575,6 +568,7 @@ public:
virtual RS::LightBakeMode light_get_bake_mode(RID p_light) override;
virtual uint32_t light_get_max_sdfgi_cascade(RID p_light) override;
virtual uint64_t light_get_version(RID p_light) const override;
virtual uint32_t light_get_cull_mask(RID p_light) const override;
Dependency *light_get_dependency(RID p_light) const;

View file

@ -1906,7 +1906,7 @@ void TextureStorage::decal_set_cull_mask(RID p_decal, uint32_t p_layers) {
Decal *decal = decal_owner.get_or_null(p_decal);
ERR_FAIL_COND(!decal);
decal->cull_mask = p_layers;
decal->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_AABB);
decal->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_DECAL);
}
void TextureStorage::decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length) {
@ -1952,6 +1952,13 @@ AABB TextureStorage::decal_get_aabb(RID p_decal) const {
return AABB(-decal->size / 2, decal->size);
}
uint32_t TextureStorage::decal_get_cull_mask(RID p_decal) const {
Decal *decal = decal_owner.get_or_null(p_decal);
ERR_FAIL_COND_V(!decal, 0);
return decal->cull_mask;
}
Dependency *TextureStorage::decal_get_dependency(RID p_decal) {
Decal *decal = decal_owner.get_or_null(p_decal);
ERR_FAIL_COND_V(!decal, nullptr);

View file

@ -638,6 +638,7 @@ public:
}
virtual AABB decal_get_aabb(RID p_decal) const override;
virtual uint32_t decal_get_cull_mask(RID p_decal) const override;
Dependency *decal_get_dependency(RID p_decal);
/* DECAL INSTANCE API */

View file

@ -1787,6 +1787,7 @@ void RendererSceneCull::_update_instance(Instance *p_instance) {
pair.pair_allocator = &pair_allocator;
pair.pair_pass = pair_pass;
pair.pair_mask = 0;
pair.cull_mask = 0xFFFFFFFF;
if ((1 << p_instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) {
pair.pair_mask |= 1 << RS::INSTANCE_LIGHT;
@ -1807,12 +1808,14 @@ void RendererSceneCull::_update_instance(Instance *p_instance) {
pair.pair_mask |= (1 << RS::INSTANCE_VOXEL_GI);
pair.bvh2 = &p_instance->scenario->indexers[Scenario::INDEXER_VOLUMES];
}
pair.cull_mask = RSG::light_storage->light_get_cull_mask(p_instance->base);
} else if (geometry_instance_pair_mask & (1 << RS::INSTANCE_REFLECTION_PROBE) && (p_instance->base_type == RS::INSTANCE_REFLECTION_PROBE)) {
pair.pair_mask = RS::INSTANCE_GEOMETRY_MASK;
pair.bvh = &p_instance->scenario->indexers[Scenario::INDEXER_GEOMETRY];
} else if (geometry_instance_pair_mask & (1 << RS::INSTANCE_DECAL) && (p_instance->base_type == RS::INSTANCE_DECAL)) {
pair.pair_mask = RS::INSTANCE_GEOMETRY_MASK;
pair.bvh = &p_instance->scenario->indexers[Scenario::INDEXER_GEOMETRY];
pair.cull_mask = RSG::texture_storage->decal_get_cull_mask(p_instance->base);
} else if (p_instance->base_type == RS::INSTANCE_PARTICLES_COLLISION) {
pair.pair_mask = (1 << RS::INSTANCE_PARTICLES);
pair.bvh = &p_instance->scenario->indexers[Scenario::INDEXER_GEOMETRY];

View file

@ -733,11 +733,12 @@ 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))) {
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)) {
//test is more coarse in indexer
p_instance->pair_check = pair_pass;
InstancePair *pair = pair_allocator->alloc();

View file

@ -84,6 +84,7 @@ public:
virtual RS::LightBakeMode light_get_bake_mode(RID p_light) = 0;
virtual uint32_t light_get_max_sdfgi_cascade(RID p_light) = 0;
virtual uint64_t light_get_version(RID p_light) const = 0;
virtual uint32_t light_get_cull_mask(RID p_light) const = 0;
/* LIGHT INSTANCE API */

View file

@ -118,6 +118,7 @@ public:
virtual void decal_set_normal_fade(RID p_decal, float p_fade) = 0;
virtual AABB decal_get_aabb(RID p_decal) const = 0;
virtual uint32_t decal_get_cull_mask(RID p_decal) const = 0;
virtual void texture_add_to_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) = 0;
virtual void texture_remove_from_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) = 0;