Fix: Eevee-next world only probe didn't update

When scenes only have a world probe the world probe had several
artifacts.

- The first sample didn't update the world.
- When switching between viewports the world didn't get updates
- When rendering it ignored the resolution that was set by the user

The reason was that the ubo was only updated when the probes where
synced. This PR adds an exception to also update when there is only
the world probe.

Pull Request: https://projects.blender.org/blender/blender/pulls/110238
This commit is contained in:
Jeroen Bakker
2023-07-18 11:58:00 +02:00
parent d9277b19f3
commit d82cbcaa96
3 changed files with 22 additions and 5 deletions

View File

@@ -39,6 +39,7 @@ void ReflectionProbeModule::init()
nullptr,
9999);
GPU_texture_mipmap_mode(probes_tx_, true, true);
probes_tx_.clear(float4(0.0f));
recalc_lod_factors();
data_buf_.push_update();
@@ -91,8 +92,16 @@ void ReflectionProbeModule::sync_world(::World *world, WorldHandle & /*ob_handle
{
const ReflectionProbe &probe = probes_.lookup(world_object_key_);
ReflectionProbeData &probe_data = data_buf_[probe.index];
probe_data.layer_subdivision = layer_subdivision_for(
int requested_layer_subdivision = layer_subdivision_for(
max_resolution_, static_cast<eLightProbeResolution>(world->probe_resolution));
if (requested_layer_subdivision != probe_data.layer_subdivision) {
ReflectionProbeData new_probe_data = find_empty_reflection_probe_data(
requested_layer_subdivision);
probe_data.layer = new_probe_data.layer;
probe_data.layer_subdivision = new_probe_data.layer_subdivision;
probe_data.area_index = new_probe_data.area_index;
do_world_update_set(true);
}
}
void ReflectionProbeModule::sync_object(Object *ob, ObjectHandle &ob_handle)
@@ -279,8 +288,9 @@ void ReflectionProbeModule::end_sync()
{
remove_unused_probes();
const bool probe_sync_done = instance_.do_probe_sync();
if (!probe_sync_done) {
const bool do_update = instance_.do_probe_sync() ||
(has_only_world_probe() && do_world_update_get());
if (!do_update) {
return;
}
@@ -296,6 +306,7 @@ void ReflectionProbeModule::end_sync()
nullptr,
9999);
GPU_texture_mipmap_mode(probes_tx_, true, true);
probes_tx_.clear(float4(0.0f));
for (ReflectionProbe &probe : probes_.values()) {
probe.do_update_data = true;
@@ -375,6 +386,11 @@ void ReflectionProbeModule::do_world_update_set(bool value)
world_probe.do_render = value;
}
bool ReflectionProbeModule::has_only_world_probe() const
{
return probes_.size() == 1;
}
/* -------------------------------------------------------------------- */
/** \name Debugging
*

View File

@@ -168,6 +168,8 @@ class ReflectionProbeModule {
void remap_to_octahedral_projection(uint64_t object_key);
void update_probes_texture_mipmaps();
bool has_only_world_probe() const;
/* Capture View requires access to the cube-maps texture for frame-buffer configuration. */
friend class CaptureView;
/* Instance requires access to #update_probes_this_sample_ */

View File

@@ -88,9 +88,8 @@ void World::sync()
}
WorldHandle &wo_handle = inst_.sync.sync_world(bl_world);
inst_.reflection_probes.sync_world(bl_world, wo_handle);
if (wo_handle.recalc != 0) {
inst_.reflection_probes.sync_world(bl_world, wo_handle);
inst_.reflection_probes.do_world_update_set(true);
}
wo_handle.reset_recalc_flag();