Add queue_update() method to ReflectionProbe

Co-authored-by: Calinou <hugo.locurcio@hugo.pro>
This commit is contained in:
Jonathan Nicholl 2022-09-15 20:10:30 -04:00
parent c2babb6558
commit c2a3b6e797
13 changed files with 53 additions and 1 deletions

View File

@ -11,6 +11,15 @@
<tutorials>
<link title="Reflection probes">$DOCS_URL/tutorials/3d/reflection_probes.html</link>
</tutorials>
<methods>
<method name="queue_update">
<return type="void" />
<description>
Queues an update of the ReflectionProbe cubemap and ambient lighting. The update will not be visible immediately; it typically takes 6 frames for the update to be visible (since 1 cubemap face is rendered per frame). [method queue_update] should be called [i]after[/i] modifying nearby objects to ensure the reflection remains up-to-date.
[b]Note:[/b] [method queue_update] only has an effect when [member update_mode] is [constant UPDATE_ONCE].
</description>
</method>
</methods>
<members>
<member name="ambient_color" type="Color" setter="set_ambient_color" getter="get_ambient_color" default="Color(0, 0, 0, 1)">
The custom ambient color to use within the [ReflectionProbe]'s [member extents]. Only effective if [member ambient_mode] is [constant AMBIENT_COLOR].
@ -58,7 +67,7 @@
</members>
<constants>
<constant name="UPDATE_ONCE" value="0" enum="UpdateMode">
Update the probe once on the next frame (recommended for most objects). The corresponding radiance map will be generated over the following six frames. This takes more time to update than [constant UPDATE_ALWAYS], but it has a lower performance cost and can result in higher-quality reflections. The ReflectionProbe is updated when its transform changes, but not when nearby geometry changes. You can force a [ReflectionProbe] update by moving the [ReflectionProbe] slightly in any direction.
Update the probe once on the next frame (recommended for most cases). The corresponding radiance map will be generated over the following six frames. This takes more time to update than [constant UPDATE_ALWAYS], but it has a lower performance cost and can result in higher-quality reflections. The ReflectionProbe is updated when its transform changes, but not when nearby geometry changes. You can force a [ReflectionProbe] update using [method queue_update].
</constant>
<constant name="UPDATE_ALWAYS" value="1" enum="UpdateMode">
Update the probe every frame. This provides better results for fast-moving dynamic objects (such as cars). However, it has a significant performance cost. Due to the cost, it's recommended to only use one ReflectionProbe with [constant UPDATE_ALWAYS] at most per scene. For all other use cases, use [constant UPDATE_ONCE].

View File

@ -2580,6 +2580,14 @@
To place in a scene, attach this reflection probe to an instance using [method instance_set_base] using the returned RID.
</description>
</method>
<method name="reflection_probe_queue_update">
<return type="void" />
<param index="0" name="probe" type="RID" />
<description>
Queues an update of the reflection probe cubemap and ambient lighting. The update will not be visible immediately; it typically takes 6 frames for the update to be visible (since 1 cubemap face is rendered per frame). [method reflection_probe_queue_update] should be called [i]after[/i] modifying nearby objects to ensure the reflection remains up-to-date.
[b]Note:[/b] [method reflection_probe_queue_update] only has an effect when the update mode is [constant REFLECTION_PROBE_UPDATE_ONCE]. Equivalent to [method ReflectionProbe.queue_update].
</description>
</method>
<method name="reflection_probe_set_ambient_color">
<return type="void" />
<param index="0" name="probe" type="RID" />

View File

@ -384,6 +384,9 @@ void LightStorage::reflection_probe_set_cull_mask(RID p_probe, uint32_t p_layers
void LightStorage::reflection_probe_set_resolution(RID p_probe, int p_resolution) {
}
void LightStorage::reflection_probe_queue_update(RID p_probe) {
}
AABB LightStorage::reflection_probe_get_aabb(RID p_probe) const {
return AABB();
}

View File

@ -289,6 +289,8 @@ public:
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;
virtual void reflection_probe_queue_update(RID p_probe) override;
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;

View File

@ -171,6 +171,15 @@ ReflectionProbe::UpdateMode ReflectionProbe::get_update_mode() const {
return update_mode;
}
void ReflectionProbe::queue_update() {
// Queuing an update only makes sense when the update mode is set to Once.
if (update_mode != UPDATE_ONCE) {
return;
}
RS::get_singleton()->reflection_probe_queue_update(probe);
}
AABB ReflectionProbe::get_aabb() const {
AABB aabb;
aabb.position = -origin_offset;
@ -226,6 +235,8 @@ void ReflectionProbe::_bind_methods() {
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);
ClassDB::bind_method(D_METHOD("queue_update"), &ReflectionProbe::queue_update);
ADD_PROPERTY(PropertyInfo(Variant::INT, "update_mode", PROPERTY_HINT_ENUM, "Once (Fast),Always (Slow)"), "set_update_mode", "get_update_mode");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "intensity", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_intensity", "get_intensity");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "max_distance", PROPERTY_HINT_RANGE, "0,16384,0.1,or_greater,exp,suffix:m"), "set_max_distance", "get_max_distance");

View File

@ -112,6 +112,8 @@ public:
void set_update_mode(UpdateMode p_mode);
UpdateMode get_update_mode() const;
void queue_update();
virtual AABB get_aabb() const override;
ReflectionProbe();

View File

@ -102,6 +102,8 @@ public:
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; }
virtual void reflection_probe_queue_update(RID p_probe) override {}
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; }

View File

@ -510,6 +510,13 @@ void LightStorage::reflection_probe_set_baked_exposure(RID p_probe, float p_expo
reflection_probe->baked_exposure = p_exposure;
}
void LightStorage::reflection_probe_queue_update(RID p_probe) {
ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
ERR_FAIL_COND(!reflection_probe);
reflection_probe->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_REFLECTION_PROBE);
}
AABB LightStorage::reflection_probe_get_aabb(RID p_probe) const {
const ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);
ERR_FAIL_COND_V(!reflection_probe, AABB());

View File

@ -283,6 +283,8 @@ public:
void reflection_probe_set_baked_exposure(RID p_probe, float p_exposure);
virtual void reflection_probe_queue_update(RID p_probe) override;
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;

View File

@ -394,6 +394,7 @@ public:
FUNC2(reflection_probe_set_cull_mask, RID, uint32_t)
FUNC2(reflection_probe_set_resolution, RID, int)
FUNC2(reflection_probe_set_mesh_lod_threshold, RID, float)
FUNC1(reflection_probe_queue_update, RID)
/* LIGHTMAP */

View File

@ -105,6 +105,8 @@ public:
virtual void reflection_probe_set_cull_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 void reflection_probe_queue_update(RID p_probe) = 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;

View File

@ -1964,6 +1964,7 @@ void RenderingServer::_bind_methods() {
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_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);
ClassDB::bind_method(D_METHOD("reflection_probe_queue_update", "probe"), &RenderingServer::reflection_probe_queue_update);
BIND_ENUM_CONSTANT(REFLECTION_PROBE_UPDATE_ONCE);
BIND_ENUM_CONSTANT(REFLECTION_PROBE_UPDATE_ALWAYS);

View File

@ -542,6 +542,8 @@ public:
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;
virtual void reflection_probe_queue_update(RID p_probe) = 0;
/* DECAL API */
enum DecalTexture {