From 5e971e8d7f798ca5fa6cc7c907fa2b1b70a99a57 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 26 May 2023 12:21:44 +0200 Subject: [PATCH] Fix hiding receiver disabling light/shadow linking Turns out it is not enough to check for the receiver/blocker set, as the object might be hidden. This should not change the light behavior. Pull Request: https://projects.blender.org/blender/blender/pulls/108307 --- intern/cycles/scene/light.cpp | 18 ++++++++++++++++++ intern/cycles/scene/light.h | 4 ++++ intern/cycles/scene/object.cpp | 26 ++++++++++++++++++++++++++ intern/cycles/scene/object.h | 5 +++++ intern/cycles/scene/scene.cpp | 11 +++++++++-- 5 files changed, 62 insertions(+), 2 deletions(-) diff --git a/intern/cycles/scene/light.cpp b/intern/cycles/scene/light.cpp index b23603115c4..c574f3fd2c9 100644 --- a/intern/cycles/scene/light.cpp +++ b/intern/cycles/scene/light.cpp @@ -174,6 +174,24 @@ bool Light::has_contribution(Scene *scene) return !is_zero(effective_shader->emission_estimate); } +bool Light::has_light_linking() const +{ + if (get_light_set_membership() != LIGHT_LINK_MASK_ALL) { + return true; + } + + return false; +} + +bool Light::has_shadow_linking() const +{ + if (get_shadow_set_membership() != LIGHT_LINK_MASK_ALL) { + return true; + } + + return false; +} + /* Light Manager */ LightManager::LightManager() diff --git a/intern/cycles/scene/light.h b/intern/cycles/scene/light.h index 7523224950e..734dab14ae2 100644 --- a/intern/cycles/scene/light.h +++ b/intern/cycles/scene/light.h @@ -82,6 +82,10 @@ class Light : public Node { /* Check whether the light has contribution the scene. */ bool has_contribution(Scene *scene); + /* Check whether this light participates in light or shadow linking. */ + bool has_light_linking() const; + bool has_shadow_linking() const; + friend class LightManager; friend class LightTree; }; diff --git a/intern/cycles/scene/object.cpp b/intern/cycles/scene/object.cpp index 0776d61dd4a..edd2cb44f11 100644 --- a/intern/cycles/scene/object.cpp +++ b/intern/cycles/scene/object.cpp @@ -403,6 +403,32 @@ bool Object::usable_as_light() const return false; } +bool Object::has_light_linking() const +{ + if (get_receiver_light_set()) { + return true; + } + + if (get_light_set_membership() != LIGHT_LINK_MASK_ALL) { + return true; + } + + return false; +} + +bool Object::has_shadow_linking() const +{ + if (get_blocker_shadow_set()) { + return true; + } + + if (get_shadow_set_membership() != LIGHT_LINK_MASK_ALL) { + return true; + } + + return false; +} + /* Object Manager */ ObjectManager::ObjectManager() diff --git a/intern/cycles/scene/object.h b/intern/cycles/scene/object.h index a91a16bc6ef..1cfcddb3d60 100644 --- a/intern/cycles/scene/object.h +++ b/intern/cycles/scene/object.h @@ -113,6 +113,11 @@ class Object : public Node { /* Check whether this object can be used as light-emissive. */ bool usable_as_light() const; + /* Check whether the object participates in light or shadow linking, either as a receiver/blocker + * or emitter. */ + bool has_light_linking() const; + bool has_shadow_linking() const; + protected: /* Specifies the position of the object in scene->objects and * in the device vectors. Gets set in device_update. */ diff --git a/intern/cycles/scene/scene.cpp b/intern/cycles/scene/scene.cpp index e2ce840bbd8..9ebd200675e 100644 --- a/intern/cycles/scene/scene.cpp +++ b/intern/cycles/scene/scene.cpp @@ -491,10 +491,10 @@ void Scene::update_kernel_features() else if (geom->is_pointcloud()) { kernel_features |= KERNEL_FEATURE_POINTCLOUD; } - if (object->get_receiver_light_set()) { + if (object->has_light_linking()) { kernel_features |= KERNEL_FEATURE_LIGHT_LINKING; } - if (object->get_blocker_shadow_set()) { + if (object->has_shadow_linking()) { kernel_features |= KERNEL_FEATURE_SHADOW_LINKING; } } @@ -503,6 +503,13 @@ void Scene::update_kernel_features() if (light->get_use_caustics()) { has_caustics_light = true; } + + if (light->has_light_linking()) { + kernel_features |= KERNEL_FEATURE_LIGHT_LINKING; + } + if (light->has_shadow_linking()) { + kernel_features |= KERNEL_FEATURE_SHADOW_LINKING; + } } dscene.data.integrator.use_caustics = false;