在试图找出如何在OpenGL / GLSL中实现kd树的一天后,我非常沮丧......
我在GLSL中声明我的KD节点:
layout(std140) uniform node{
ivec4 splitPoint;
int dataPtr;
} nodes[1024];
SplitPoint保存kd树分割点,向量的第四个元素保持splitDirection在3d空间中形成一个平面。 DataPtr目前只在树的叶子中保存随机值。
整个数组形成Ahnentafel List。
在C ++中,结构如下所示:
struct Node{
glm::ivec4 splitPoint;
GLint dataPtr;
GLint padding[3];
};
我相信这是正确的,我将构建的树上传到缓冲区。作为检查,我将缓冲区映射到主存储器并检查值:
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
看起来很好(它实际上说节点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);
此时屏幕上应该有随机颜色的图案。但在大多数情况下,没有什么可看的。
我试图直接从节点获取值并获得正确的结果......所以我认为统一块数据的动态索引存在问题。
我希望有人可以在这里帮助我......因为我的想法已经用完了:/
弗洛里安
答案 0 :(得分:4)
甜蜜:glm和布局:)(你碰巧知道Groovounet吗?)
我相信我在这里看到一些奇怪的事情
您决定树的哪一侧递归的标准很奇怪。你期望它做什么?绝对不是kd-tree walk。你有权访问最近的ShaderX吗?我相信#5给出了这个
您的数据也很奇怪(也许:您是否100%确定分裂点?)
也许您应该检查std140是否真的被考虑在内。但是你的C ++ Node看起来还不错。