我正在研究一个Opengl射线跟踪器,它能够加载obj文件并对其进行射线跟踪。我的应用程序使用assimp加载obj文件,然后通过使用着色器存储对象将所有三角形面(顶点和索引)发送到片段着色器。基本结构即将把结果从片段着色器渲染到四边形。
当我加载较大的obj-s(超过100个三角形)时,计算机花费大量时间进行交点,因此我开始创建BVH树来加快该过程。我的BVH根据AABB中包含的三角形面的平均中值,将空间递归分成两个轴对齐的边界框。
我成功地(在CPU上)构建了BVH树结构,现在我想将其转换为简单的数组,然后将其发送到片段着色器(到着色器存储缓冲区)。
这是我的BVH课程的结构。
class BvhNode { public: BBox bBox; vector<BvhNode> children; bool isLeaf; int depthOfNode; vector<glm::vec3> primitiveCoordinates; BvhNode() {} ~BvhNode() {} BvhNode(vector<glm::vec3> &primitiveCoordinates) { this->primitiveCoordinates = primitiveCoordinates; } void buildTree(vector<glm::vec3> &indicesPerFaces, int depth) {...} glm::vec3 calculateCenterofTriangle(glm::vec3 vec, glm::vec3 vec1, glm::vec3 vec2) {...} glm::vec3 getCoordinatefromIndices(float index) {...} BBox getBBox(vector<glm::vec3> &indices) {...} };
但是首先,我想将其转换为简单的数组,因为GLSL不支持指针。我已经读过有关可以将二叉树转换为数组的课程(当然,如果该树是完整的)。我正在拔头发。我如何遍历整个节点(包括子节点),以及如何用空节点完成它(以满足完整二叉树的定义)?我开始编写如下所示的方法,但是当我将
nodes
变量声明为全局变量时遇到了分段错误。我不知道为什么。
vector<BvhNode> nodes; // it is a global variable void putNodeIntoArray(BvhNode node) { nodes.push_back(node.children.at(0)); nodes.push_back(node.children.at(1)); }
我猜,当我创建树时,需要在左右两个子节点开始的每个节点中以某种方式签名。
感谢您的任何帮助。
我正在研究一个Opengl射线跟踪器,它能够加载obj文件并对其进行射线跟踪。我的应用程序使用assimp加载obj文件,然后发送所有三角形面(顶点和...
布局数组中的二叉树节点的一种方法是:对于树中的所有节点,如果给定节点的数组索引为i
,则其子节点位于索引2i + 1
和2i + 2
(更完整地描述[ C0])。