views:

87

answers:

1

Hi everybody,

after one day of trying to figure out how to implement a kd-tree in OpenGL/GLSL i am pretty frustrated ...

I declare my KD-Nodes like this in GLSL:

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

SplitPoint holds the kd-tree splitpoint, the fourth element of the vector holds the splitDirection forming a plane in 3d space. DataPtr currently only holds random values in the leafs of the tree.

The whole array forms a Ahnentafel List.

In C++ the structure looks like this:

struct Node{
  glm::ivec4 splitPoint;
  GLint dataPtr;
  GLint padding[3];
};

I believe that to be correct and i upload the constructed tree in the buffer. As a check i map the buffer into main memory and inspect the values:

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

Looking good sofar (it actually says that the volume is split at (0,256,0) in y direction in node 0, -1 is the sign for no data).

Now for the tree traversal i tried this:

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);

At this point there should be a pattern of random colors onscreen. But in most cases there is nothing to be seen.

I tried to get values from nodes directly and get correct results ... so i believe there is something wrong with the dynamic indexing of the uniform block data.

I hope someone can help me here ... cause i am running out of ideas :/

Florian

A: 

Sweet : glm AND layouts :) ( Do you happen to know Groovounet ? )

I believe I see some weird things here

  • Your criterion for deciding on which side of the tree to recurse is strange. What do you expect it to do ? Definitely not a kd-tree walk. Do you have access to a recent ShaderX ? I believe the #5 gives actual code for this

  • Your data is weird too (maybe : are you 100% sure of the splitting points ?)

Maybe you should check that std140 is really taken into account. But you C++ Node seems ok though.

Calvin1602
- The criterion is based on the data ... or abscence of the same. -1 indicates that there is no data present in the node so i have to recurse, as soon as the pointer is at the leafs there is data- The data is just not normalized. It's in the range of 0..511. The criterion which child to traverse in is based on a simple plane to point comparison ( distFromPlane = dot(point-pointOnPlane,normalOfPlane); ) When I manually set 'n' to a node and output the distanceFromPlane variable as gl_Fragcolor.r it is calculated correct. My best guess is that the problem is related to dynamic branching
Florian
And: no i don't know groovounet ;)But at least glm vectors are layed out in memory perfectly and you can use them directly in UBOs.
Florian
I meant it is NOT a KD-tree traversal. It will eventually select the first intersected volume, but it doesn't necessarily contain anything, does it ?
Calvin1602
are you 100% sure of splitDir ? How do you compute it ? 1 -> +Y, 2->+Z, etc ? **And btw, you don't update it in the while.**
Calvin1602
Ah sorry ... yes i removed the code for it above.I'll just put it back in there.Why should it select the first intersecting volume?I'd say it goes straight through to the 'bottom' of the tree where there is data.
Florian
I mean : the first volume that a ray cast from the camera would intersect. It goes both towards the bottom of the tree and towards the camera, i.e the nodes INSIDE the tree will never ever be visited, whatever the view angle. This may or may not be your problem, but in any case I don't think that it's really what you want.
Calvin1602
No.... thats true. The idea was to compare a point to the tree. To find the value that suited that point best
Florian
In that case I can just suggest you to try with a tiny tree, for instance only 1 leaf or 1 root and 2 leaves. Sorry :/
Calvin1602
No problem ... i think the problem is that it's not possible to do 'dynamic lookups' from uniform objects here.Possibly it would work better if i'd use a texture buffer to store the data.
Florian