2013-07-26 13 views
5

Voglio usare il buffer di profondità in modo leggermente non ortodosso e sono stato pesantemente confuso da tutta la normalizzazione, il ridimensionamento e tutto ciò che accade lì.Come utilizzare il buffer di profondità per memorizzare gli indici

Il mio piano è di implementare un algoritmo di hashing spaziale da parte di alcuni ragazzi di AMD (link to pdf).

tl; dr-version: velocizza la ricerca del vicino più vicino, discretizzando i vertici 3D in una serie di trame di profondità (2D piatte), impostando la profondità sul VertexID. Il motivo per cui si utilizzano trame di profondità è che ci sono alcuni test di approfondimento intelligenti in corso per ottenere i risultati in un ordine ordinato, ma qui è meno importante.

mio problema è che il VertexID è ovviamente un numero intero, che vanno dal 0 alla quantità totale di vertici ParticleCount, ma che non può essere utilizzato direttamente, come uscita del vertex deve essere normalizzati a [-1..1) in OpenGL (o [0..1) in DirectX).

mio vertex shader fa quindi qualcosa di simile:

float depth = 2.0 * gl_VertexID/ParticleCount - 1.0; 
gl_Position = vec4(flatCoords, depth, 1.0); 

Questo è tipo di lavorazione, ma quali valori sono in realtà memorizzati alla texture di profondità legata al framebuffer corrente mi confonde. Non ho proprio la differenza tra il depth buffer a virgola mobile e la versione intera, se non riesco nemmeno a produrre interi reali e durante la lettura dalla texture di profondità in seguito tutto sembra essere normalizzato a [0..1] indipendentemente dal formato interno Ho impostato (DepthComponent24, 32, 32f).

Qualcuno può darmi qualche consiglio su come estrarre i VertexID da queste trame di profondità?

Grazie

+0

"* normalizzato a [-1..1) in OpenGL (o [0..1) in DirectX * "L'1 è compreso in entrambi i casi. –

+0

Hai ragione, una leggera svista. Ma il comportamento predefinito del test di profondità sta eliminando il buffer di profondità su 1 e utilizzando il confronto "minore di", quindi tutti i punti con una profondità di 1 vengono abbattuti. – Gigo

risposta

1

uscita dal vertex in OpenGL dopo divide prospettiva viene troncato [-1,1], che significa gl_Position.z/gl_Position.w deve essere in tale intervallo. Tuttavia, il valore di profondità effettivamente memorizzato nel buffer di profondità viene rimappato sull'intervallo 0..1 utilizzando i valori di intervallo di profondità corrente (glDepthRange). Per default la gamma profondità è 0..1, che si traduce in

depth_buf_value = 0.5 + 0.5 * gl_Position.z/gl_Position.w; 

Quindi nel caso in cui il buffer di profondità infine contiene valori di galleggiante (gl_VertexID)/ParticleCount, e quindi:

vertex_id = depth_buf_value * ParticleCount 
+0

Ok, questo conferma che quello che ho cercato di fare avrebbe dovuto funzionare, ma non è così. Proverò a tornare presto a questo progetto per farlo funzionare. – Gigo

+0

Un altro pensiero che ho avuto: per quanto riguarda la precisione? Il formato interno che è usato per il depth buffer mi confonde un po '. È gestito come un float, ma memorizzato come int normalizzato? Questo influenza l'intervallo che può essere rappresentato? Il ParticleCount potrebbe benissimo essere un milione o più e devo essere in grado di ripristinare in modo affidabile l'indice di particelle dal buffer di profondità. – Gigo

+1

Un valore in virgola mobile nell'intervallo 0..1 viene convertito in un formato interno specificato. Dovresti ottenere la stessa precisione con il formato intero a 24 bit e il formato a virgola mobile entrambi, poiché quest'ultimo ha una mantissa a 24 bit (23 + bit implicito iniziale), che può essere utilizzato per rappresentare interi senza perdita di bit. Tuttavia, poiché in OpenGL passa attraverso quella parte di rimappatura, almeno un bit di tale precisione viene perso.Ma questo lascia ancora 23 bit con valori distinti> 8 ml. – camenomizoratojoakizunewake