2010-07-29 63 views
5
一天试图找出如何实现在OpenGL/GLSL kd树我很沮丧......

KD树在GLSL

我宣布我的KD-节点像这样的GLSL

后:

layout(std140) uniform node{ 
    ivec4 splitPoint; 
    int dataPtr; 
} nodes[1024]; 

SplitPoint保存kd-tree分割点,向量的第四个元素使splitDirection在三维空间中形成一个平面。 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,256,0在y方向上在节点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); 

在这一点上应该有随机颜色屏幕上的图案。但在大多数情况下,没有什么可以看到的。

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

我希望有人能帮助我在这里...因为我运行的想法:/

弗洛里安

回答

4

甜:(?你碰巧知道Groovounet)GLM和布局:)

我相信我看到一些奇怪的事情在这里

  • 你的标准来决定哪些树的侧递归很奇怪。你期望它做什么?肯定不是kd树行走。你有没有使用最近的ShaderX?我相信,#5给你的数据是怪异过这个

  • 实际代码(也许:你是100%肯定的分割点?)

也许你应该检查std140真的采取考虑到。但是,你的C++节点似乎确定,但。

+0

- 该标准基于数据...或相同的缺陷。 -1表示没有数据出现在节点中,所以我必须递归,只要指针在叶子上就有数据 - 数据只是未标准化。它的范围是0..511。孩子要穿过的标准是基于一个简单的平面点比较(distFromPlane = dot(point-pointOnPlane,normalOfPlane);) 当我手动设置'n'节点并输出distanceFromPlane变量为gl_Fragcolor.r它计算正确。我最好的猜测是,这个问题与动态分支有关 – fho 2010-08-02 07:23:06

+0

并且:不,我不知道groovounet;) 但是至少glm向量完美地放置在内存中,您可以直接在UBO中使用它们。 – fho 2010-08-02 07:24:05

+0

我的意思是它不是KD树遍历。它最终会选择第一个相交的卷,但它不一定包含任何内容,是吗? – Calvin1602 2010-08-02 08:10:33