[Bf-blender-cvs] [166c0db3f94] master: Fix T83915: Subdivision Surface modifier causes visual artifacts in Cycles rendered viewport - CPU and OptiX

Patrick Mours noreply at git.blender.org
Tue Jan 5 18:00:13 CET 2021


Commit: 166c0db3f9412925b501b7172875cb8ee2eb6958
Author: Patrick Mours
Date:   Tue Jan 5 14:39:29 2021 +0100
Branches: master
https://developer.blender.org/rB166c0db3f9412925b501b7172875cb8ee2eb6958

Fix T83915: Subdivision Surface modifier causes visual artifacts in Cycles rendered viewport - CPU and OptiX

Changing the geometry in the current scene caused the primitive offsets for all geometry to
change, but the values would not be updated in all bottom-level BVH structures. Rendering
artifacts and crashes where the result. This fixes that by ensuring all BVH structures are
updated when the primitive offsets change.

===================================================================

M	intern/cycles/bvh/bvh_embree.cpp
M	intern/cycles/render/geometry.cpp
M	intern/cycles/render/geometry.h

===================================================================

diff --git a/intern/cycles/bvh/bvh_embree.cpp b/intern/cycles/bvh/bvh_embree.cpp
index b874bda7186..c082478e5b1 100644
--- a/intern/cycles/bvh/bvh_embree.cpp
+++ b/intern/cycles/bvh/bvh_embree.cpp
@@ -682,6 +682,7 @@ void BVHEmbree::refit(Progress &progress)
         if (mesh->num_triangles() > 0) {
           RTCGeometry geom = rtcGetGeometry(scene, geom_id);
           set_tri_vertex_buffer(geom, mesh, true);
+          rtcSetGeometryUserData(geom, (void *)mesh->optix_prim_offset);
           rtcCommitGeometry(geom);
         }
       }
@@ -690,6 +691,7 @@ void BVHEmbree::refit(Progress &progress)
         if (hair->num_curves() > 0) {
           RTCGeometry geom = rtcGetGeometry(scene, geom_id + 1);
           set_curve_vertex_buffer(geom, hair, true);
+          rtcSetGeometryUserData(geom, (void *)hair->optix_prim_offset);
           rtcCommitGeometry(geom);
         }
       }
diff --git a/intern/cycles/render/geometry.cpp b/intern/cycles/render/geometry.cpp
index 64b98a91853..6fc217f2d76 100644
--- a/intern/cycles/render/geometry.cpp
+++ b/intern/cycles/render/geometry.cpp
@@ -280,6 +280,15 @@ void Geometry::tag_update(Scene *scene, bool rebuild)
   scene->object_manager->need_update = true;
 }
 
+void Geometry::tag_bvh_update(bool rebuild)
+{
+  tag_modified();
+
+  if (rebuild) {
+    need_update_rebuild = true;
+  }
+}
+
 /* Geometry Manager */
 
 GeometryManager::GeometryManager()
@@ -915,7 +924,7 @@ void GeometryManager::device_update_attributes(Device *device,
   scene->object_manager->device_update_mesh_offsets(device, dscene, scene);
 }
 
-void GeometryManager::mesh_calc_offset(Scene *scene)
+void GeometryManager::mesh_calc_offset(Scene *scene, BVHLayout bvh_layout)
 {
   size_t vert_size = 0;
   size_t tri_size = 0;
@@ -930,6 +939,14 @@ void GeometryManager::mesh_calc_offset(Scene *scene)
   size_t optix_prim_size = 0;
 
   foreach (Geometry *geom, scene->geometry) {
+    if (geom->optix_prim_offset != optix_prim_size) {
+      /* Need to rebuild BVH in OptiX, since refit only allows modified mesh data there */
+      const bool has_optix_bvh = bvh_layout == BVH_LAYOUT_OPTIX ||
+                                 bvh_layout == BVH_LAYOUT_MULTI_OPTIX ||
+                                 bvh_layout == BVH_LAYOUT_MULTI_OPTIX_EMBREE;
+      geom->tag_bvh_update(has_optix_bvh);
+    }
+
     if (geom->geometry_type == Geometry::MESH || geom->geometry_type == Geometry::VOLUME) {
       Mesh *mesh = static_cast<Mesh *>(geom);
 
@@ -1526,7 +1543,9 @@ void GeometryManager::device_update(Device *device,
   /* Device update. */
   device_free(device, dscene);
 
-  mesh_calc_offset(scene);
+  const BVHLayout bvh_layout = BVHParams::best_bvh_layout(scene->params.bvh_layout,
+                                                          device->get_bvh_layout_mask());
+  mesh_calc_offset(scene, bvh_layout);
   if (true_displacement_used) {
     scoped_callback_timer timer([scene](double time) {
       if (scene->update_stats) {
@@ -1553,8 +1572,6 @@ void GeometryManager::device_update(Device *device,
   }
 
   /* Update displacement. */
-  BVHLayout bvh_layout = BVHParams::best_bvh_layout(scene->params.bvh_layout,
-                                                    device->get_bvh_layout_mask());
   bool displacement_done = false;
   size_t num_bvh = 0;
 
diff --git a/intern/cycles/render/geometry.h b/intern/cycles/render/geometry.h
index d3daf0cc809..b124e950ad2 100644
--- a/intern/cycles/render/geometry.h
+++ b/intern/cycles/render/geometry.h
@@ -157,6 +157,8 @@ class Geometry : public Node {
 
   /* Updates */
   void tag_update(Scene *scene, bool rebuild);
+
+  void tag_bvh_update(bool rebuild);
 };
 
 /* Geometry Manager */
@@ -198,7 +200,7 @@ class GeometryManager {
                              vector<AttributeRequestSet> &object_attributes);
 
   /* Compute verts/triangles/curves offsets in global arrays. */
-  void mesh_calc_offset(Scene *scene);
+  void mesh_calc_offset(Scene *scene, BVHLayout bvh_layout);
 
   void device_update_object(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress);



More information about the Bf-blender-cvs mailing list