2010-07-29 21 views
5

un día después de tratar de encontrar la manera de poner en práctica un kd-árbol en OpenGL/GLSL estoy bastante frustrado ...KD-Árbol en GLSL

declaro mis KD-nodos como este en GLSL:

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

SplitPoint tiene el punto de división kd-tree, el cuarto elemento del vector contiene la divisiónDirección formando un plano en el espacio 3D. DataPtr actualmente solo contiene valores aleatorios en las hojas del árbol.

Toda la matriz forma un Ahnentafel List.

En C++ la estructura se parece a esto:

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

creo que eso sea correcto y puedo subir el árbol construido en el búfer. Como comprobación i mapa la memoria intermedia en la memoria principal e inspeccionar los valores:

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 

Mirando buena sofar (que realmente dice que el volumen se divide en (0,256,0) en la dirección y en el nodo 0, -1 es el signo de no datos).

Ahora para el recorrido del árbol He intentado esto:

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

En este punto no debe haber un patrón de colores al azar en pantalla. Pero en la mayoría de los casos no hay nada que ver.

Intenté obtener los valores de los nodos directamente y obtener los resultados correctos ... así que creo que hay algún problema con la indexación dinámica de los datos de bloque uniformes.

espero que alguien me puede ayudar aquí ... porque yo estoy quedando sin ideas:/

Florian

Respuesta

4

dulce: (? ¿Por casualidad saber Groovounet) GLM y diseños :)

creo que veo algunas cosas extrañas aquí

  • su criterio para decidir en qué lado del árbol para recursivo es extraño. ¿Qué esperas que haga? Definitivamente no es una caminata de kd. ¿Tienes acceso a un ShaderX reciente? Creo que el # 5 proporciona código real para este

  • Sus datos es raro también (tal vez: ¿estás seguro al 100% de los puntos de división?)

tal vez debería comprobar que std140 es realmente tomada en cuenta. Pero tu C++ Node parece estar bien.

+0

- El criterio se basa en los datos ... o la ausencia del mismo. -1 indica que no hay datos presentes en el nodo, así que tengo que recurse, tan pronto como el puntero esté en las hojas hay datos - Los datos simplemente no están normalizados. Está en el rango de 0..511. El criterio a través del cual se desplaza el niño se basa en una comparación simple de plano a punto (distFromPlane = dot (point-pointOnPlane, normalOfPlane);) Cuando configuro manualmente 'n' en un nodo y saco la variable distanceFromPlane como gl_Fragcolor.r se calcula correcto.Mi mejor estimación es que el problema está relacionado con la ramificación dinámica – fho

+0

Y: no, no lo sé groovounet;) Pero al menos los vectores glm se disponen perfectamente en la memoria y se pueden usar directamente en UBO. – fho

+0

Quise decir que NO es un cruce de árbol KD. Eventualmente seleccionará el primer volumen intersecado, pero no necesariamente contiene nada, ¿verdad? – Calvin1602