2010-07-29 11 views
5

dopo un giorno di cercare di capire come implementare un kd-albero in OpenGL/GLSL Sono abbastanza frustrato ...KD-Albero in GLSL

dichiaro la mia KD-nodi come questo in GLSL:

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

SplitPoint detiene il punto di divisione di kd-tree, il quarto elemento del vettore contiene lo splitDirection che forma un piano nello spazio 3d. DataPtr attualmente contiene solo valori casuali nelle foglie dell'albero.

L'intero array costituisce un Ahnentafel List.

In C++ la struttura si presenta così:

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

Credo che per essere corretto e posso caricare l'albero costruito nel buffer. Come controllo I mappa buffer nella memoria principale e controllare i valori:

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 

guardando bene sofar (si dice in realtà che il volume è suddiviso in (0,256,0) in direzione y in nodo 0, -1 è il segno per nessun dato).

Ora per l'attraversamento dell'albero Ho provato questo:

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

A questo punto ci dovrebbe essere un modello di colori casuali sullo schermo. Ma nella maggior parte dei casi non c'è nulla da vedere.

Ho cercato di ottenere direttamente i valori dai nodi e ottenere risultati corretti ... quindi credo che ci sia qualcosa di sbagliato nell'indicizzazione dinamica dei dati di blocco uniformi.

Spero che qualcuno mi può aiutare qui ... Perché io sono a corto di idee:/

Florian

risposta

4

dolce: (? Ti capita di conoscere Groovounet) glm e layout :)

credo di vedere alcune cose strane qui

  • vostro criterio per decidere su quale lato dell'albero di ricorsione è strano. Cosa ti aspetti che faccia? Sicuramente non è una passeggiata kd-tree. Hai accesso a un recente ShaderX? Credo che il # 5 dà codice vero e proprio per questo

  • tuoi dati sono strano troppo (forse: sei sicuro al 100% dei punti di divisione?)

Forse si dovrebbe verificare che std140 è davvero preso in considerazione. Ma il nodo C++ sembra comunque ok.

+0

- Il criterio si basa sui dati ... o sull'abscenza degli stessi. -1 indica che non ci sono dati presenti nel nodo, quindi devo recurse, non appena il puntatore è alle foglie ci sono dati - I dati non sono solo normalizzati. È nell'intervallo di 0,511. Il criterio con cui il bambino deve attraversare è basato su un semplice confronto piano-punto (distFromPlane = punto (point-pointOnPlane, normalOfPlane);) Quando imposto manualmente 'n' su un nodo e restituisco la variabile distanceFromPlane come gl_Fragcolor.r it è calcolato corretto.La mia ipotesi migliore è che il problema sia relativo alle diramazioni dinamiche – fho

+0

E: no non lo so groovounet;) Ma almeno i vettori glm sono disposti perfettamente nella memoria e puoi usarli direttamente nelle UBO. – fho

+0

Intendevo dire che NON è un attraversamento di alberi KD. Alla fine selezionerà il primo volume intersecato, ma non necessariamente contiene qualcosa, vero? – Calvin1602