Bladeren bron

Implement cull_mask for decals and lights in mobile and compatibility backends

clayjohn 2 jaren geleden
bovenliggende
commit
56450fb179

+ 7 - 0
drivers/gles3/storage/light_storage.cpp

@@ -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());

+ 1 - 7
drivers/gles3/storage/light_storage.h

@@ -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 */
 

+ 1 - 0
drivers/gles3/storage/texture_storage.h

@@ -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 {}

+ 1 - 0
servers/rendering/dummy/storage/light_storage.h

@@ -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 */
 

+ 1 - 0
servers/rendering/dummy/storage/texture_storage.h

@@ -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 {}

+ 7 - 0
servers/rendering/renderer_rd/storage_rd/light_storage.cpp

@@ -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());

+ 1 - 7
servers/rendering/renderer_rd/storage_rd/light_storage.h

@@ -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;
 

+ 8 - 1
servers/rendering/renderer_rd/storage_rd/texture_storage.cpp

@@ -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);

+ 1 - 0
servers/rendering/renderer_rd/storage_rd/texture_storage.h

@@ -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 */

+ 3 - 0
servers/rendering/renderer_scene_cull.cpp

@@ -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];

+ 2 - 1
servers/rendering/renderer_scene_cull.h

@@ -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();

+ 1 - 0
servers/rendering/storage/light_storage.h

@@ -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 */
 

+ 1 - 0
servers/rendering/storage/texture_storage.h

@@ -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;