[Bf-blender-cvs] [b4ae962447e] master: Cycles: Switched Embree to use Catmull-Rom curves.

Stefan Werner noreply at git.blender.org
Thu Feb 20 13:05:37 CET 2020


Commit: b4ae962447ed7611c1f357416a1c049e0de5dca9
Author: Stefan Werner
Date:   Thu Feb 20 10:28:32 2020 +0100
Branches: master
https://developer.blender.org/rBb4ae962447ed7611c1f357416a1c049e0de5dca9

Cycles: Switched Embree to use Catmull-Rom curves.

The latest versions of Embree support Catmull-Rom splines
which use less memory than the previously used Hermite splines.
The representation is also much closer to Cycles own data structures
and can hopefully be unified in the future for more memory savings.

Memory savings using Victor benchmark scene:
Compared to previous Embree: ~400MB
Compared to Cycles' native BVH: ~1GB

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

M	intern/cycles/bvh/bvh_embree.cpp

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

diff --git a/intern/cycles/bvh/bvh_embree.cpp b/intern/cycles/bvh/bvh_embree.cpp
index 84b00aab91c..f621c5c0dd4 100644
--- a/intern/cycles/bvh/bvh_embree.cpp
+++ b/intern/cycles/bvh/bvh_embree.cpp
@@ -727,6 +727,11 @@ void BVHEmbree::update_curve_vertex_buffer(RTCGeometry geom_id, const Hair *hair
     num_keys += c.num_keys;
   }
 
+  /* Catmull-Rom splines need extra CVs at the beginning and end of each curve. */
+  if (use_curves) {
+    num_keys += num_curves * 2;
+  }
+
   /* Copy the CV data to Embree */
   const int t_mid = (num_motion_steps - 1) / 2;
   const float *curve_radius = &hair->curve_radius[0];
@@ -742,37 +747,23 @@ void BVHEmbree::update_curve_vertex_buffer(RTCGeometry geom_id, const Hair *hair
 
     float4 *rtc_verts = (float4 *)rtcSetNewGeometryBuffer(
         geom_id, RTC_BUFFER_TYPE_VERTEX, t, RTC_FORMAT_FLOAT4, sizeof(float) * 4, num_keys);
-    float4 *rtc_tangents = NULL;
-    if (use_curves) {
-      rtc_tangents = (float4 *)rtcSetNewGeometryBuffer(
-          geom_id, RTC_BUFFER_TYPE_TANGENT, t, RTC_FORMAT_FLOAT4, sizeof(float) * 4, num_keys);
-      assert(rtc_tangents);
-    }
+
     assert(rtc_verts);
     if (rtc_verts) {
-      if (use_curves && rtc_tangents) {
+      if (use_curves) {
         const size_t num_curves = hair->num_curves();
         for (size_t j = 0; j < num_curves; ++j) {
           Hair::Curve c = hair->get_curve(j);
           int fk = c.first_key;
-          rtc_verts[0] = float3_to_float4(verts[fk]);
-          rtc_verts[0].w = curve_radius[fk];
-          rtc_tangents[0] = float3_to_float4(verts[fk + 1] - verts[fk]);
-          rtc_tangents[0].w = curve_radius[fk + 1] - curve_radius[fk];
-          ++fk;
           int k = 1;
-          for (; k < c.num_segments(); ++k, ++fk) {
+          for (; k < c.num_keys + 1; ++k, ++fk) {
             rtc_verts[k] = float3_to_float4(verts[fk]);
             rtc_verts[k].w = curve_radius[fk];
-            rtc_tangents[k] = float3_to_float4((verts[fk + 1] - verts[fk - 1]) * 0.5f);
-            rtc_tangents[k].w = (curve_radius[fk + 1] - curve_radius[fk - 1]) * 0.5f;
           }
-          rtc_verts[k] = float3_to_float4(verts[fk]);
-          rtc_verts[k].w = curve_radius[fk];
-          rtc_tangents[k] = float3_to_float4(verts[fk] - verts[fk - 1]);
-          rtc_tangents[k].w = curve_radius[fk] - curve_radius[fk - 1];
-          rtc_verts += c.num_keys;
-          rtc_tangents += c.num_keys;
+          /* Duplicate Embree's Catmull-Rom spline CVs at the start and end of each curve. */
+          rtc_verts[0] = rtc_verts[1];
+          rtc_verts[k] = rtc_verts[k - 1];
+          rtc_verts += c.num_keys + 2;
         }
       }
       else {
@@ -820,8 +811,8 @@ void BVHEmbree::add_curves(const Object *ob, const Hair *hair, int i)
 
   enum RTCGeometryType type = (!use_curves) ?
                                   RTC_GEOMETRY_TYPE_FLAT_LINEAR_CURVE :
-                                  (use_ribbons ? RTC_GEOMETRY_TYPE_FLAT_HERMITE_CURVE :
-                                                 RTC_GEOMETRY_TYPE_ROUND_HERMITE_CURVE);
+                                  (use_ribbons ? RTC_GEOMETRY_TYPE_FLAT_CATMULL_ROM_CURVE :
+                                                 RTC_GEOMETRY_TYPE_ROUND_CATMULL_ROM_CURVE);
 
   RTCGeometry geom_id = rtcNewGeometry(rtc_shared_device, type);
   rtcSetGeometryTessellationRate(geom_id, curve_subdivisions);
@@ -832,6 +823,10 @@ void BVHEmbree::add_curves(const Object *ob, const Hair *hair, int i)
     Hair::Curve c = hair->get_curve(j);
     for (size_t k = 0; k < c.num_segments(); ++k) {
       rtc_indices[rtc_index] = c.first_key + k;
+      if (use_curves) {
+        /* Room for extra CVs at Catmull-Rom splines. */
+        rtc_indices[rtc_index] += j * 2;
+      }
       /* Cycles specific data. */
       pack.prim_object[prim_object_size + rtc_index] = i;
       pack.prim_type[prim_type_size + rtc_index] = (PRIMITIVE_PACK_SEGMENT(



More information about the Bf-blender-cvs mailing list