GLSL中的KD-Tree

fho*_*fho 5 c++ opengl glsl kdtree

在试图弄清楚如何在OpenGL/GLSL中实现kd树之后的一天,我非常沮丧......

我在GLSL中声明我的KD节点:

layout(std140) uniform node{
  ivec4 splitPoint;
  int dataPtr;
} nodes[1024];
Run Code Online (Sandbox Code Playgroud)

SplitPoint保存kd树分割点,向量的第四个元素保持splitDirection在3d空间中形成一个平面.DataPtr目前仅在树的叶子中保存随机值.

整个阵列形成一个Ahnentafel列表.

在C++中,结构如下所示:

struct Node{
  glm::ivec4 splitPoint;
  GLint dataPtr;
  GLint padding[3];
};
Run Code Online (Sandbox Code Playgroud)

我相信这是正确的,我上传构造的树在缓冲区.作为检查,我将缓冲区映射到主内存并检查值:

0x08AB6890     +0  +256    +0    +1    -1  -858993460  -858993460  -858993460
0x08AB68B0   +256    +0    +0    +0    -1  -858993460  -858993460  -858993460
0x08AB68D0   +256  +256    +0    +0    -1  -858993460  -858993460  -858993460
[...]
0x08AB7070     +0    +0    +0    +0 +2362  -858993460  -858993460  -858993460
Run Code Online (Sandbox Code Playgroud)

看起来很好(它实际上说节点0中的音量在y方向上被分割为(0,256,0),-1是没有数据的符号).

现在为树遍历我尝试了这个:

float distanceFromSplitPlane;
while(nodes[n].dataPtr == -1){

  // get split direction
  vec3 splitDir = vec3(0,0,0);
  if(nodes[n].splitDir == 0)
    splitDir.x = 1;
  else if(nodes[n].splitDir == 1)
    splitDir.y = 1;
  else 
    splitDir.z = 1;


  // calculate distance of ray starting point to the split plane
  distanceFromSplitPlane = dot(startP.xyz-(nodes[n].splitPoint.xyz/511.0), splitDir);

  // depending on the side advance in the tree
  if(distanceFromSplitPlane >= 0)
    n = 2 * n + 1;
  else
    n = 2 * n + 2;
}

// we should new be located in a leaf node and therefor have a value in dataPtr
gl_FragColor = vec4(dataPtr/6000.0, 0,1,1);
Run Code Online (Sandbox Code Playgroud)

此时屏幕上应该有随机颜色的图案.但在大多数情况下,没有什么可看的.

我试图直接从节点获取值并得到正确的结果......所以我认为统一块数据的动态索引存在问题.

我希望有人能在这里帮助我......因为我的想法已经不多了:/

弗洛里安

Cal*_*602 4

Sweet : glm 和布局:)(你碰巧知道 Groovounet 吗?)

我相信我在这里看到了一些奇怪的东西

  • 您决定在树的哪一侧递归的标准很奇怪。您期望它做什么?绝对不是 kd 树行走。您可以访问最新的 ShaderX 吗?我相信 #5 给出了实际的代码

  • 你的数据也很奇怪(也许:你100%确定分裂点吗?)

也许您应该检查是否确实考虑了 std140。但你的 C++ Node 看起来还不错。