diff --git a/doc/classes/ReflectionProbe.xml b/doc/classes/ReflectionProbe.xml
index f53ddfc3ac34..c7d067b94d38 100644
--- a/doc/classes/ReflectionProbe.xml
+++ b/doc/classes/ReflectionProbe.xml
@@ -28,7 +28,8 @@
[b]Note:[/b] To better fit rectangle-shaped rooms that are not aligned to the grid, you can rotate the [ReflectionProbe] node.
- Sets the cull mask which determines what objects are drawn by this probe. Every [VisualInstance3D] with a layer included in this cull mask will be rendered by the probe. To improve performance, it is best to only include large objects which are likely to take up a lot of space in the reflection.
+ Sets the cull mask which determines what objects are drawn by this probe. Every [VisualInstance3D] with a layer included in this cull mask will be rendered by the probe. It is best to only include large objects which are likely to take up a lot of space in the reflection in order to save on rendering cost.
+ This can also be used to prevent an object from reflecting upon itself (for instance, a [ReflectionProbe] centered on a vehicle).
If [code]true[/code], computes shadows in the reflection probe. This makes the reflection probe slower to render; you may want to disable this if using the [constant UPDATE_ALWAYS] [member update_mode].
@@ -50,6 +51,9 @@
Sets the origin offset to be used when this [ReflectionProbe] is in [member box_projection] mode. This can be set to a non-zero value to ensure a reflection fits a rectangle-shaped room, while reducing the number of objects that "get in the way" of the reflection.
+
+ Sets the reflection mask which determines what objects have reflections applied from this probe. Every [VisualInstance3D] with a layer included in this reflection mask will have reflections applied from this probe. See also [member cull_mask], which can be used to exclude objects from appearing in the reflection while still making them affected by the [ReflectionProbe].
+
The size of the reflection probe. The larger the size, the more space covered by the probe, which will lower the perceived resolution. It is best to keep the size only as large as you need it.
[b]Note:[/b] To better fit areas that are not aligned to the grid, you can rotate the [ReflectionProbe] node.
diff --git a/doc/classes/RenderingServer.xml b/doc/classes/RenderingServer.xml
index 42a164bbeb74..4ab511b5a908 100644
--- a/doc/classes/RenderingServer.xml
+++ b/doc/classes/RenderingServer.xml
@@ -2894,7 +2894,7 @@
- Sets the render cull mask for this reflection probe. Only instances with a matching cull mask will be rendered by this probe. Equivalent to [member ReflectionProbe.cull_mask].
+ Sets the render cull mask for this reflection probe. Only instances with a matching layer will be reflected by this probe. Equivalent to [member ReflectionProbe.cull_mask].
@@ -2945,6 +2945,14 @@
Sets the origin offset to be used when this reflection probe is in box project mode. Equivalent to [member ReflectionProbe.origin_offset].
+
+
+
+
+
+ Sets the render reflection mask for this reflection probe. Only instances with a matching layer will have reflections applied from this probe. Equivalent to [member ReflectionProbe.reflection_mask].
+
+
diff --git a/drivers/gles3/storage/light_storage.cpp b/drivers/gles3/storage/light_storage.cpp
index 2607a133d6d2..5421f5764611 100644
--- a/drivers/gles3/storage/light_storage.cpp
+++ b/drivers/gles3/storage/light_storage.cpp
@@ -468,6 +468,9 @@ void LightStorage::reflection_probe_set_enable_shadows(RID p_probe, bool p_enabl
void LightStorage::reflection_probe_set_cull_mask(RID p_probe, uint32_t p_layers) {
}
+void LightStorage::reflection_probe_set_reflection_mask(RID p_probe, uint32_t p_layers) {
+}
+
void LightStorage::reflection_probe_set_resolution(RID p_probe, int p_resolution) {
}
@@ -483,6 +486,10 @@ uint32_t LightStorage::reflection_probe_get_cull_mask(RID p_probe) const {
return 0;
}
+uint32_t LightStorage::reflection_probe_get_reflection_mask(RID p_probe) const {
+ return 0;
+}
+
Vector3 LightStorage::reflection_probe_get_size(RID p_probe) const {
return Vector3();
}
diff --git a/drivers/gles3/storage/light_storage.h b/drivers/gles3/storage/light_storage.h
index 7ab02860989b..96e62002198d 100644
--- a/drivers/gles3/storage/light_storage.h
+++ b/drivers/gles3/storage/light_storage.h
@@ -575,6 +575,7 @@ class LightStorage : public RendererLightStorage {
virtual void reflection_probe_set_enable_box_projection(RID p_probe, bool p_enable) override;
virtual void reflection_probe_set_enable_shadows(RID p_probe, bool p_enable) override;
virtual void reflection_probe_set_cull_mask(RID p_probe, uint32_t p_layers) override;
+ virtual void reflection_probe_set_reflection_mask(RID p_probe, uint32_t p_layers) override;
virtual void reflection_probe_set_resolution(RID p_probe, int p_resolution) override;
virtual void reflection_probe_set_mesh_lod_threshold(RID p_probe, float p_ratio) override;
virtual float reflection_probe_get_mesh_lod_threshold(RID p_probe) const override;
@@ -582,6 +583,7 @@ class LightStorage : public RendererLightStorage {
virtual AABB reflection_probe_get_aabb(RID p_probe) const override;
virtual RS::ReflectionProbeUpdateMode reflection_probe_get_update_mode(RID p_probe) const override;
virtual uint32_t reflection_probe_get_cull_mask(RID p_probe) const override;
+ virtual uint32_t reflection_probe_get_reflection_mask(RID p_probe) const override;
virtual Vector3 reflection_probe_get_size(RID p_probe) const override;
virtual Vector3 reflection_probe_get_origin_offset(RID p_probe) const override;
virtual float reflection_probe_get_origin_max_distance(RID p_probe) const override;
diff --git a/scene/3d/reflection_probe.cpp b/scene/3d/reflection_probe.cpp
index 2e34f6aad029..b4dd6d09be3a 100644
--- a/scene/3d/reflection_probe.cpp
+++ b/scene/3d/reflection_probe.cpp
@@ -165,6 +165,15 @@ uint32_t ReflectionProbe::get_cull_mask() const {
return cull_mask;
}
+void ReflectionProbe::set_reflection_mask(uint32_t p_layers) {
+ reflection_mask = p_layers;
+ RS::get_singleton()->reflection_probe_set_reflection_mask(probe, p_layers);
+}
+
+uint32_t ReflectionProbe::get_reflection_mask() const {
+ return reflection_mask;
+}
+
void ReflectionProbe::set_update_mode(UpdateMode p_mode) {
update_mode = p_mode;
RS::get_singleton()->reflection_probe_set_update_mode(probe, RS::ReflectionProbeUpdateMode(p_mode));
@@ -237,6 +246,9 @@ void ReflectionProbe::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_cull_mask", "layers"), &ReflectionProbe::set_cull_mask);
ClassDB::bind_method(D_METHOD("get_cull_mask"), &ReflectionProbe::get_cull_mask);
+ ClassDB::bind_method(D_METHOD("set_reflection_mask", "layers"), &ReflectionProbe::set_reflection_mask);
+ ClassDB::bind_method(D_METHOD("get_reflection_mask"), &ReflectionProbe::get_reflection_mask);
+
ClassDB::bind_method(D_METHOD("set_update_mode", "mode"), &ReflectionProbe::set_update_mode);
ClassDB::bind_method(D_METHOD("get_update_mode"), &ReflectionProbe::get_update_mode);
@@ -249,6 +261,7 @@ void ReflectionProbe::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "interior"), "set_as_interior", "is_set_as_interior");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enable_shadows"), "set_enable_shadows", "are_shadows_enabled");
ADD_PROPERTY(PropertyInfo(Variant::INT, "cull_mask", PROPERTY_HINT_LAYERS_3D_RENDER), "set_cull_mask", "get_cull_mask");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "reflection_mask", PROPERTY_HINT_LAYERS_3D_RENDER), "set_reflection_mask", "get_reflection_mask");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "mesh_lod_threshold", PROPERTY_HINT_RANGE, "0,1024,0.1"), "set_mesh_lod_threshold", "get_mesh_lod_threshold");
ADD_GROUP("Ambient", "ambient_");
diff --git a/scene/3d/reflection_probe.h b/scene/3d/reflection_probe.h
index 5438219d5e79..425fbb5bc2eb 100644
--- a/scene/3d/reflection_probe.h
+++ b/scene/3d/reflection_probe.h
@@ -63,6 +63,7 @@ class ReflectionProbe : public VisualInstance3D {
float mesh_lod_threshold = 1.0;
uint32_t cull_mask = (1 << 20) - 1;
+ uint32_t reflection_mask = (1 << 20) - 1;
UpdateMode update_mode = UPDATE_ONCE;
protected:
@@ -113,6 +114,9 @@ class ReflectionProbe : public VisualInstance3D {
void set_cull_mask(uint32_t p_layers);
uint32_t get_cull_mask() const;
+ void set_reflection_mask(uint32_t p_layers);
+ uint32_t get_reflection_mask() const;
+
void set_update_mode(UpdateMode p_mode);
UpdateMode get_update_mode() const;
diff --git a/servers/rendering/dummy/storage/light_storage.h b/servers/rendering/dummy/storage/light_storage.h
index a9a7beb387ab..61a825f8c58f 100644
--- a/servers/rendering/dummy/storage/light_storage.h
+++ b/servers/rendering/dummy/storage/light_storage.h
@@ -109,6 +109,7 @@ class LightStorage : public RendererLightStorage {
virtual void reflection_probe_set_enable_box_projection(RID p_probe, bool p_enable) override {}
virtual void reflection_probe_set_enable_shadows(RID p_probe, bool p_enable) override {}
virtual void reflection_probe_set_cull_mask(RID p_probe, uint32_t p_layers) override {}
+ virtual void reflection_probe_set_reflection_mask(RID p_probe, uint32_t p_layers) override {}
virtual void reflection_probe_set_resolution(RID p_probe, int p_resolution) override {}
virtual void reflection_probe_set_mesh_lod_threshold(RID p_probe, float p_ratio) override {}
virtual float reflection_probe_get_mesh_lod_threshold(RID p_probe) const override { return 0.0; }
@@ -116,6 +117,7 @@ class LightStorage : public RendererLightStorage {
virtual AABB reflection_probe_get_aabb(RID p_probe) const override { return AABB(); }
virtual RS::ReflectionProbeUpdateMode reflection_probe_get_update_mode(RID p_probe) const override { return RenderingServer::REFLECTION_PROBE_UPDATE_ONCE; }
virtual uint32_t reflection_probe_get_cull_mask(RID p_probe) const override { return 0; }
+ virtual uint32_t reflection_probe_get_reflection_mask(RID p_probe) const override { return 0; }
virtual Vector3 reflection_probe_get_size(RID p_probe) const override { return Vector3(); }
virtual Vector3 reflection_probe_get_origin_offset(RID p_probe) const override { return Vector3(); }
virtual float reflection_probe_get_origin_max_distance(RID p_probe) const override { return 0.0; }
diff --git a/servers/rendering/renderer_rd/storage_rd/light_storage.cpp b/servers/rendering/renderer_rd/storage_rd/light_storage.cpp
index 150e82c25c5b..2786af65ebc1 100644
--- a/servers/rendering/renderer_rd/storage_rd/light_storage.cpp
+++ b/servers/rendering/renderer_rd/storage_rd/light_storage.cpp
@@ -1119,6 +1119,14 @@ void LightStorage::reflection_probe_set_cull_mask(RID p_probe, uint32_t p_layers
reflection_probe->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_REFLECTION_PROBE);
}
+void LightStorage::reflection_probe_set_reflection_mask(RID p_probe, uint32_t p_layers) {
+ ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
+ ERR_FAIL_NULL(reflection_probe);
+
+ reflection_probe->reflection_mask = p_layers;
+ reflection_probe->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_REFLECTION_PROBE);
+}
+
void LightStorage::reflection_probe_set_resolution(RID p_probe, int p_resolution) {
ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
ERR_FAIL_NULL(reflection_probe);
@@ -1168,6 +1176,13 @@ uint32_t LightStorage::reflection_probe_get_cull_mask(RID p_probe) const {
return reflection_probe->cull_mask;
}
+uint32_t LightStorage::reflection_probe_get_reflection_mask(RID p_probe) const {
+ const ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
+ ERR_FAIL_NULL_V(reflection_probe, 0);
+
+ return reflection_probe->reflection_mask;
+}
+
Vector3 LightStorage::reflection_probe_get_size(RID p_probe) const {
const ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
ERR_FAIL_NULL_V(reflection_probe, Vector3());
@@ -1681,7 +1696,7 @@ void LightStorage::update_reflection_probe_buffer(RenderDataRD *p_render_data, c
Vector3 extents = probe->size / 2;
- rpi->cull_mask = probe->cull_mask;
+ rpi->cull_mask = probe->reflection_mask;
reflection_ubo.box_extents[0] = extents.x;
reflection_ubo.box_extents[1] = extents.y;
@@ -1693,7 +1708,7 @@ void LightStorage::update_reflection_probe_buffer(RenderDataRD *p_render_data, c
reflection_ubo.box_offset[0] = origin_offset.x;
reflection_ubo.box_offset[1] = origin_offset.y;
reflection_ubo.box_offset[2] = origin_offset.z;
- reflection_ubo.mask = probe->cull_mask;
+ reflection_ubo.mask = probe->reflection_mask;
reflection_ubo.intensity = probe->intensity;
reflection_ubo.ambient_mode = probe->ambient_mode;
diff --git a/servers/rendering/renderer_rd/storage_rd/light_storage.h b/servers/rendering/renderer_rd/storage_rd/light_storage.h
index f5b846362a44..45226ec47cae 100644
--- a/servers/rendering/renderer_rd/storage_rd/light_storage.h
+++ b/servers/rendering/renderer_rd/storage_rd/light_storage.h
@@ -232,6 +232,7 @@ class LightStorage : public RendererLightStorage {
bool box_projection = false;
bool enable_shadows = false;
uint32_t cull_mask = (1 << 20) - 1;
+ uint32_t reflection_mask = (1 << 20) - 1;
float mesh_lod_threshold = 0.01;
float baked_exposure = 1.0;
@@ -797,6 +798,7 @@ class LightStorage : public RendererLightStorage {
virtual void reflection_probe_set_enable_box_projection(RID p_probe, bool p_enable) override;
virtual void reflection_probe_set_enable_shadows(RID p_probe, bool p_enable) override;
virtual void reflection_probe_set_cull_mask(RID p_probe, uint32_t p_layers) override;
+ virtual void reflection_probe_set_reflection_mask(RID p_probe, uint32_t p_layers) override;
virtual void reflection_probe_set_resolution(RID p_probe, int p_resolution) override;
virtual void reflection_probe_set_mesh_lod_threshold(RID p_probe, float p_ratio) override;
@@ -805,6 +807,7 @@ class LightStorage : public RendererLightStorage {
virtual AABB reflection_probe_get_aabb(RID p_probe) const override;
virtual RS::ReflectionProbeUpdateMode reflection_probe_get_update_mode(RID p_probe) const override;
virtual uint32_t reflection_probe_get_cull_mask(RID p_probe) const override;
+ virtual uint32_t reflection_probe_get_reflection_mask(RID p_probe) const override;
virtual Vector3 reflection_probe_get_size(RID p_probe) const override;
virtual Vector3 reflection_probe_get_origin_offset(RID p_probe) const override;
virtual float reflection_probe_get_origin_max_distance(RID p_probe) const override;
diff --git a/servers/rendering/rendering_server_default.h b/servers/rendering/rendering_server_default.h
index e8b20692f0fa..9ad1d8b8dcac 100644
--- a/servers/rendering/rendering_server_default.h
+++ b/servers/rendering/rendering_server_default.h
@@ -401,6 +401,7 @@ class RenderingServerDefault : public RenderingServer {
FUNC2(reflection_probe_set_enable_box_projection, RID, bool)
FUNC2(reflection_probe_set_enable_shadows, RID, bool)
FUNC2(reflection_probe_set_cull_mask, RID, uint32_t)
+ FUNC2(reflection_probe_set_reflection_mask, RID, uint32_t)
FUNC2(reflection_probe_set_resolution, RID, int)
FUNC2(reflection_probe_set_mesh_lod_threshold, RID, float)
diff --git a/servers/rendering/storage/light_storage.h b/servers/rendering/storage/light_storage.h
index c1f79cfc4924..27407305d161 100644
--- a/servers/rendering/storage/light_storage.h
+++ b/servers/rendering/storage/light_storage.h
@@ -118,11 +118,13 @@ class RendererLightStorage {
virtual void reflection_probe_set_enable_box_projection(RID p_probe, bool p_enable) = 0;
virtual void reflection_probe_set_enable_shadows(RID p_probe, bool p_enable) = 0;
virtual void reflection_probe_set_cull_mask(RID p_probe, uint32_t p_layers) = 0;
+ virtual void reflection_probe_set_reflection_mask(RID p_probe, uint32_t p_layers) = 0;
virtual void reflection_probe_set_mesh_lod_threshold(RID p_probe, float p_ratio) = 0;
virtual AABB reflection_probe_get_aabb(RID p_probe) const = 0;
virtual RS::ReflectionProbeUpdateMode reflection_probe_get_update_mode(RID p_probe) const = 0;
virtual uint32_t reflection_probe_get_cull_mask(RID p_probe) const = 0;
+ virtual uint32_t reflection_probe_get_reflection_mask(RID p_probe) const = 0;
virtual Vector3 reflection_probe_get_size(RID p_probe) const = 0;
virtual Vector3 reflection_probe_get_origin_offset(RID p_probe) const = 0;
virtual float reflection_probe_get_origin_max_distance(RID p_probe) const = 0;
diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp
index 27e677bce03d..99b1c5631a7e 100644
--- a/servers/rendering_server.cpp
+++ b/servers/rendering_server.cpp
@@ -2551,6 +2551,7 @@ void RenderingServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("reflection_probe_set_enable_box_projection", "probe", "enable"), &RenderingServer::reflection_probe_set_enable_box_projection);
ClassDB::bind_method(D_METHOD("reflection_probe_set_enable_shadows", "probe", "enable"), &RenderingServer::reflection_probe_set_enable_shadows);
ClassDB::bind_method(D_METHOD("reflection_probe_set_cull_mask", "probe", "layers"), &RenderingServer::reflection_probe_set_cull_mask);
+ ClassDB::bind_method(D_METHOD("reflection_probe_set_reflection_mask", "probe", "layers"), &RenderingServer::reflection_probe_set_reflection_mask);
ClassDB::bind_method(D_METHOD("reflection_probe_set_resolution", "probe", "resolution"), &RenderingServer::reflection_probe_set_resolution);
ClassDB::bind_method(D_METHOD("reflection_probe_set_mesh_lod_threshold", "probe", "pixels"), &RenderingServer::reflection_probe_set_mesh_lod_threshold);
diff --git a/servers/rendering_server.h b/servers/rendering_server.h
index 958c21f893b7..b395104629e5 100644
--- a/servers/rendering_server.h
+++ b/servers/rendering_server.h
@@ -572,6 +572,7 @@ class RenderingServer : public Object {
virtual void reflection_probe_set_enable_box_projection(RID p_probe, bool p_enable) = 0;
virtual void reflection_probe_set_enable_shadows(RID p_probe, bool p_enable) = 0;
virtual void reflection_probe_set_cull_mask(RID p_probe, uint32_t p_layers) = 0;
+ virtual void reflection_probe_set_reflection_mask(RID p_probe, uint32_t p_layers) = 0;
virtual void reflection_probe_set_resolution(RID p_probe, int p_resolution) = 0;
virtual void reflection_probe_set_mesh_lod_threshold(RID p_probe, float p_pixels) = 0;