[Bf-blender-cvs] [43b1fc97bd8] soc-2019-embree-gpu: Add basic support for instanced mesh

MATILLAT Quentin noreply at git.blender.org
Fri Jun 28 21:55:03 CEST 2019


Commit: 43b1fc97bd88ae40a7c87a83c2a116e8c944feeb
Author: MATILLAT Quentin
Date:   Fri Jun 28 21:38:08 2019 +0200
Branches: soc-2019-embree-gpu
https://developer.blender.org/rB43b1fc97bd88ae40a7c87a83c2a116e8c944feeb

Add basic support for instanced mesh

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

M	intern/cycles/bvh/bvh.cpp
M	intern/cycles/bvh/bvh.h
M	intern/cycles/bvh/bvh2.cpp
M	intern/cycles/bvh/bvh_embree.cpp
M	intern/cycles/render/mesh.cpp

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

diff --git a/intern/cycles/bvh/bvh.cpp b/intern/cycles/bvh/bvh.cpp
index 2269ca3be3c..715651c96a8 100644
--- a/intern/cycles/bvh/bvh.cpp
+++ b/intern/cycles/bvh/bvh.cpp
@@ -129,6 +129,12 @@ BVH *BVH::create(const BVHParams &params, const vector<Object *> &objects)
 
 /* Building */
 
+void BVH::buildTimed(Progress &p, Stats *s) {
+    auto start = std::chrono::steady_clock::now();
+    this->build(p, s);
+    std::cout << std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now()-start).count() << "ms" << std::endl;
+}
+
 void BVH::build(Progress &progress, Stats *)
 {
   progress.set_substatus("Building BVH");
@@ -156,6 +162,7 @@ void BVH::build(Progress &progress, Stats *)
   if (root != bvh2_root) {
     bvh2_root->deleteSubtree();
   }
+  std::cout << "SAH " << root->computeSubtreeSAHCost(this->params) << std::endl;
 
   if (progress.get_cancel()) {
     if (root != NULL) {
diff --git a/intern/cycles/bvh/bvh.h b/intern/cycles/bvh/bvh.h
index edce3ca6f2a..65e5268c5e7 100644
--- a/intern/cycles/bvh/bvh.h
+++ b/intern/cycles/bvh/bvh.h
@@ -88,6 +88,7 @@ class BVH {
   {
   }
 
+  void buildTimed(Progress &p, Stats *s);
   virtual void build(Progress &progress, Stats *stats = NULL);
   void refit(Progress &progress);
 
diff --git a/intern/cycles/bvh/bvh2.cpp b/intern/cycles/bvh/bvh2.cpp
index f419d413ef6..fbbcb9589f0 100644
--- a/intern/cycles/bvh/bvh2.cpp
+++ b/intern/cycles/bvh/bvh2.cpp
@@ -161,6 +161,7 @@ void BVH2::pack_unaligned_node(int idx,
 
 void BVH2::pack_nodes(const BVHNode *root)
 {
+  std::cout << "BVH2 SAH is " << root->computeSubtreeSAHCost(this->params) << std::endl;
   const size_t num_nodes = root->getSubtreeSize(BVH_STAT_NODE_COUNT);
   const size_t num_leaf_nodes = root->getSubtreeSize(BVH_STAT_LEAF_COUNT);
   assert(num_leaf_nodes <= num_nodes);
diff --git a/intern/cycles/bvh/bvh_embree.cpp b/intern/cycles/bvh/bvh_embree.cpp
index 778315ddaef..5519c746fd1 100644
--- a/intern/cycles/bvh/bvh_embree.cpp
+++ b/intern/cycles/bvh/bvh_embree.cpp
@@ -66,6 +66,7 @@
 #include "embree/kernels/common/scene.h"
 #include "embree/kernels/bvh/bvh.h"
 #include "embree/kernels/geometry/trianglev.h"
+#include "embree/kernels/geometry/instance.h"
 #include "bvh_node.h"
 CCL_NAMESPACE_BEGIN
 
@@ -95,7 +96,7 @@ ccl::BoundBox RTCBoundBoxToCCL(const embree::BBox3fa &bound) {
 }
 
 template<typename Primitive>
-BVHNode* nodeEmbreeToCcl(embree::BVH4::NodeRef node, ccl::BoundBox bb, embree::Scene *s) {
+BVHNode* nodeEmbreeToCcl(embree::BVH4::NodeRef node, ccl::BoundBox bb, embree::Scene *s, vector<Object*> objects) {
     if(node.isLeaf()) {
         size_t nb;
         Primitive *prims = reinterpret_cast<Primitive *>(node.leaf(nb));
@@ -159,8 +160,8 @@ BVHNode* nodeEmbreeToCcl(embree::BVH4::NodeRef node, ccl::BoundBox bb, embree::S
                     children[i] = nodeEmbreeToCcl<Primitive>(
                                 anode->children[i],
                                 RTCBoundBoxToCCL(anode->bounds(i)),
-                                s
-                                );
+                                s,
+                                objects);
             }
 
             ret = new InnerNode(
@@ -175,10 +176,90 @@ BVHNode* nodeEmbreeToCcl(embree::BVH4::NodeRef node, ccl::BoundBox bb, embree::S
     }
 }
 
-BVHNode* print_bvhInfo(RTCScene scene) {
+template<>
+BVHNode* nodeEmbreeToCcl<embree::InstancePrimitive>(embree::BVH4::NodeRef node, ccl::BoundBox bb, embree::Scene *s, vector<Object*> objects) {
+    if(node.isLeaf()) {
+        size_t nb;
+        embree::InstancePrimitive *prims = reinterpret_cast<embree::InstancePrimitive *>(node.leaf(nb));
+
+        std::stack<LeafNode *> leafs;
+
+        for(size_t i = 0; i < nb; i++) {
+            int id = prims[i].instance->geomID;
+            // BoundBox bb(make_float3(-2, -2, -2), make_float3(4, 4, 4)); // RTCBoundBoxToCCL(prims[i].instance->bounds(0));
+            // BoundBox bb = RTCBoundBoxToCCL(prims[i].instance->object->bounds.bounds());
+            // BoundBox bb = RTCBoundBoxToCCL(prims[i].instance->linearBounds(0, embree::BBox1f(0, 1)).bounds());
+            // embree::AffineSpace3fa loc2World = prims[i].instance->getLocal2World();
+
+            LeafNode *leafNode = new LeafNode(objects.at(id)->bounds, 4294967295, id, id + 1);
+            leafs.push(leafNode);
+
+            print_float3("MIN", bb.min);
+            print_float3("MAX", bb.max);
+        }
+
+        std::deque<BVHNode *> nodes;
+        BVHNode *ret = nullptr;
+        while(!leafs.empty()) {
+            nodes.push_back(leafs.top());
+            leafs.pop();
+        }
+
+        while(!nodes.empty()) {
+            if(ret == nullptr) {
+                ret = nodes.front();
+                nodes.pop_front();
+                continue;
+            }
+
+            if(ret->is_leaf() || ret->num_children()) {
+                ret = new InnerNode(bb, &ret, 1);
+            }
+
+            InnerNode *innerNode = dynamic_cast<InnerNode*>(ret);
+            innerNode->children[innerNode->num_children_++] = nodes.front();
+            nodes.pop_front();
+
+            if(ret->num_children() == 4) {
+                nodes.push_back(ret);
+                ret = nullptr;
+            }
+        }
+
+        return ret;
+    } else {
+        InnerNode *ret = nullptr;
+
+        if(node.isAlignedNode()) {
+            embree::BVH4::AlignedNode *anode = node.alignedNode();
+
+            BVHNode *children[4];
+            for(uint i = 0; i < 4; i++) {
+                    children[i] = nodeEmbreeToCcl<embree::InstancePrimitive>(
+                                anode->children[i],
+                                RTCBoundBoxToCCL(anode->bounds(i)),
+                                s,
+                                objects);
+            }
+
+            ret = new InnerNode(
+                        bb,
+                        children,
+                        4);
+        } else {
+            std::cout << "Unknown node" << std::endl;
+        }
+
+        return ret;
+    }
+}
+
+BVHNode* print_bvhInfo(RTCScene scene, vector<Object *> objects) {
     embree::Scene *s = (embree::Scene *)scene;
 
     std::cout << "<- Accel used ->" << std::endl;
+    std::vector<BVHNode *> nodes;
+    BoundBox bb = BoundBox::empty;
     for (embree::Accel *a : s->accels) {
         std::cout << "Accel " << a->intersectors.intersector1.name << std::endl;
         embree::AccelData *ad = a->intersectors.ptr;
@@ -187,16 +268,32 @@ BVHNode* print_bvhInfo(RTCScene scene) {
             embree::BVH4 *bvh = dynamic_cast<embree::BVHN<4> *>(ad);
             std::cout << "Prim type -> " << bvh->primTy->name() << std::endl;
 
-            embree::BVH4::NodeRef root = bvh->root;
-            return nodeEmbreeToCcl<embree::Triangle4v>(root, RTCBoundBoxToCCL(bvh->bounds.bounds()), s);
-        }
+            if(bvh->primTy == &embree::Triangle4v::type) {
+                embree::BVH4::NodeRef root = bvh->root;
+                BVHNode *rootNode = nodeEmbreeToCcl<embree::Triangle4v>(root, RTCBoundBoxToCCL(bvh->bounds.bounds()), s, objects);
+                bb.grow(rootNode->bounds);
+                nodes.push_back(rootNode);
+            } else if(bvh->primTy == &embree::InstancePrimitive::type) {
+                embree::BVH4::NodeRef root = bvh->root;
+                BVHNode *rootNode = nodeEmbreeToCcl<embree::InstancePrimitive>(root, RTCBoundBoxToCCL(bvh->bounds.bounds()), s, objects);
+                bb.grow(rootNode->bounds);
+                nodes.push_back(rootNode);
+            } else {
+
+            }
+
+        } break;
         default:
             std::cout << "[EMBREE - BVH] Unknown type " << ad->type << std::endl;
             break;
         }
     }
     std::cout << "[DONE]" << std::endl;
-    return nullptr;
+
+    if(nodes.size() == 1)
+        return nodes.front();
+
+    return new InnerNode(bb, nodes.data(), nodes.size());
 }
 
 BVHNode *bvh_shrink(BVHNode *root) {
@@ -650,12 +747,11 @@ void BVHEmbree::build(Progress &progress, Stats *stats_)
 
   progress.set_substatus("Packing geometry");
   if(this->bvh_layout == BVH_LAYOUT_EMBREE_CONVERTED) {
-    BVHNode *root = print_bvhInfo(scene);
-    std::cout << "SAH4 " << root->computeSubtreeSAHCost(this->params) << std::endl;
-    root->print();
+    BVHNode *root = print_bvhInfo(scene, objects);
+    std::cout << "BVH4 SAH is " << root->computeSubtreeSAHCost(this->params) << std::endl;
     root = bvh_shrink(root);
     pack_nodes(root);
-    std::cout << "SAH2 " << root->computeSubtreeSAHCost(this->params) << std::endl;
+    std::cout << "BVH2 SAH is " << root->computeSubtreeSAHCost(this->params) << std::endl;
   } else {
     pack_nodes(NULL);
   }
diff --git a/intern/cycles/render/mesh.cpp b/intern/cycles/render/mesh.cpp
index 45cf8e3a149..edb2ef7c829 100644
--- a/intern/cycles/render/mesh.cpp
+++ b/intern/cycles/render/mesh.cpp
@@ -1904,7 +1904,7 @@ void MeshManager::device_update_bvh(Device *device,
   bparams.curve_flags = dscene->data.curve.curveflags;
   bparams.curve_subdivisions = dscene->data.curve.subdivisions;
 
-  VLOG(1) << "Using " << bvh_layout_name(bparams.bvh_layout) << " layout.";
+  std::cout << "Using " << bvh_layout_name(bparams.bvh_layout) << " layout.";
 
 #ifdef WITH_EMBREE
   if (bparams.bvh_layout == BVH_LAYOUT_EMBREE) {
@@ -1915,7 +1915,7 @@ void MeshManager::device_update_bvh(Device *device,
 #endif
 
   BVH *bvh = BVH::create(bparams, scene->objects);
-  bvh->build(progress, &device->stats);
+  bvh->buildTimed(progress, &device->stats);
 
   if (progress.get_cancel()) {
 #ifdef WITH_EMBREE



More information about the Bf-blender-cvs mailing list