diff options
-rw-r--r-- | intern/cycles/scene/geometry.cpp | 13 | ||||
-rw-r--r-- | source/blender/blenlib/BLI_string_ref.hh | 4 |
2 files changed, 16 insertions, 1 deletions
diff --git a/intern/cycles/scene/geometry.cpp b/intern/cycles/scene/geometry.cpp index 5141e1f8358..8a3fc522d22 100644 --- a/intern/cycles/scene/geometry.cpp +++ b/intern/cycles/scene/geometry.cpp @@ -1588,9 +1588,20 @@ void GeometryManager::device_update_displacement_images(Device *device, set<int> bump_images; foreach (Geometry *geom, scene->geometry) { if (geom->is_modified()) { + /* Geometry-level check for hair shadow transparency. + * This matches the logic in the `Hair::update_shadow_transparency()`, avoiding access to + * possible non-loaded images. */ + bool need_shadow_transparency = false; + if (geom->geometry_type == Geometry::HAIR) { + Hair *hair = static_cast<Hair *>(geom); + need_shadow_transparency = hair->need_shadow_transparency(); + } + foreach (Node *node, geom->get_used_shaders()) { Shader *shader = static_cast<Shader *>(node); - if (!shader->has_displacement || shader->get_displacement_method() == DISPLACE_BUMP) { + const bool is_true_displacement = (shader->has_displacement && + shader->get_displacement_method() != DISPLACE_BUMP); + if (!is_true_displacement && !need_shadow_transparency) { continue; } foreach (ShaderNode *node, shader->graph->nodes) { diff --git a/source/blender/blenlib/BLI_string_ref.hh b/source/blender/blenlib/BLI_string_ref.hh index 34baf94c448..dc73208350f 100644 --- a/source/blender/blenlib/BLI_string_ref.hh +++ b/source/blender/blenlib/BLI_string_ref.hh @@ -610,6 +610,10 @@ constexpr bool operator==(StringRef a, StringRef b) if (a.size() != b.size()) { return false; } + if (a.data() == b.data()) { + /* This also avoids passing null to the call below, which would results in an ASAN warning. */ + return true; + } return STREQLEN(a.data(), b.data(), (size_t)a.size()); } |