Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKévin Dietrich <kevin.dietrich@mailoo.org>2021-03-24 12:36:31 +0300
committerKévin Dietrich <kevin.dietrich@mailoo.org>2021-03-24 12:41:29 +0300
commit42198e9eb03bdc5494c3717c6b1643539ef06231 (patch)
treee41e4c8a230f3b3f50a5890872fd4dfadf428be5
parent6b18678e34bfbe2e95430fa7491ed1d3fad4ff3a (diff)
Fix T86601: Cycles accumulates displacement when transforming an Object
In order to update the BVH when only the transformations are changing, we would tag the Object's Geometry as modified. However, when displacement is used, and the vertices were not themselves modified, this would cause us to redo the displacement on already displaced vertices. To fix this, use a specific update flag for detecting and notifying that transformations were modified. Regression caused by rBbbe6d44928235cd4a5cfbeaf1a1de78ed861bb92.
-rw-r--r--intern/cycles/render/geometry.cpp9
-rw-r--r--intern/cycles/render/geometry.h2
-rw-r--r--intern/cycles/render/object.cpp15
-rw-r--r--intern/cycles/render/object.h1
4 files changed, 14 insertions, 13 deletions
diff --git a/intern/cycles/render/geometry.cpp b/intern/cycles/render/geometry.cpp
index e9a70e4b3fd..60a6f598ed2 100644
--- a/intern/cycles/render/geometry.cpp
+++ b/intern/cycles/render/geometry.cpp
@@ -1917,9 +1917,12 @@ void GeometryManager::device_update(Device *device,
}
}
- /* update the bvh even when there is no geometry so the kernel bvh data is still valid,
- * especially when removing all of the objects during interactive renders */
- bool need_update_scene_bvh = (scene->bvh == nullptr);
+ /* Update the BVH even when there is no geometry so the kernel's BVH data is still valid,
+ * especially when removing all of the objects during interactive renders.
+ * Also update the BVH if the transformations change, we cannot rely on tagging the Geometry
+ * as modified in this case, as we may accumulate displacement if the vertices do not also
+ * change. */
+ bool need_update_scene_bvh = (scene->bvh == nullptr || (update_flags & TRANSFORM_MODIFIED) != 0);
{
scoped_callback_timer timer([scene](double time) {
if (scene->update_stats) {
diff --git a/intern/cycles/render/geometry.h b/intern/cycles/render/geometry.h
index fe30f3a807c..abdd851a089 100644
--- a/intern/cycles/render/geometry.h
+++ b/intern/cycles/render/geometry.h
@@ -189,6 +189,8 @@ class GeometryManager {
GEOMETRY_ADDED = MESH_ADDED | HAIR_ADDED,
GEOMETRY_REMOVED = MESH_REMOVED | HAIR_REMOVED,
+ TRANSFORM_MODIFIED = (1 << 10),
+
/* tag everything in the manager for an update */
UPDATE_ALL = ~0u,
diff --git a/intern/cycles/render/object.cpp b/intern/cycles/render/object.cpp
index e71d7d4a3eb..52f63685aeb 100644
--- a/intern/cycles/render/object.cpp
+++ b/intern/cycles/render/object.cpp
@@ -221,16 +221,7 @@ void Object::tag_update(Scene *scene)
if (geometry) {
if (tfm_is_modified()) {
- /* tag the geometry as modified so the BVH is updated, but do not tag everything as modified
- */
- if (geometry->is_mesh() || geometry->is_volume()) {
- Mesh *mesh = static_cast<Mesh *>(geometry);
- mesh->tag_verts_modified();
- }
- else if (geometry->is_hair()) {
- Hair *hair = static_cast<Hair *>(geometry);
- hair->tag_curve_keys_modified();
- }
+ flag |= ObjectManager::TRANSFORM_MODIFIED;
}
foreach (Node *node, geometry->get_used_shaders()) {
@@ -923,6 +914,10 @@ void ObjectManager::tag_update(Scene *scene, uint32_t flag)
geometry_flag |= (GeometryManager::GEOMETRY_ADDED | GeometryManager::GEOMETRY_REMOVED);
}
+ if ((flag & TRANSFORM_MODIFIED) != 0) {
+ geometry_flag |= GeometryManager::TRANSFORM_MODIFIED;
+ }
+
scene->geometry_manager->tag_update(scene, geometry_flag);
}
diff --git a/intern/cycles/render/object.h b/intern/cycles/render/object.h
index cf1b9ca510a..23682270fd1 100644
--- a/intern/cycles/render/object.h
+++ b/intern/cycles/render/object.h
@@ -133,6 +133,7 @@ class ObjectManager {
OBJECT_REMOVED = (1 << 4),
OBJECT_MODIFIED = (1 << 5),
HOLDOUT_MODIFIED = (1 << 6),
+ TRANSFORM_MODIFIED = (1 << 7),
/* tag everything in the manager for an update */
UPDATE_ALL = ~0u,