2013-07-26 18 views
5

Chcę używać bufora głębi w nieco nieortodoksyjny sposób i mocno mnie zdezorientował cały proces normalizacji, skalowania i tego, co się tam dzieje.Jak korzystać z bufora głębokości do przechowywania indeksów

Mój plan to implementacja algorytmu przestrzennego mieszania przez niektórych gości z AMD (link to pdf).

tl; dr-version: Przyspieszenie wyszukiwania najbliższego sąsiada poprzez dyskretyzację wierzchołków 3D do tablicy (głębi 2D) tekstury głębi, ustawienie głębi VertexID. Powodem używania tekstur głębi jest to, że istnieją pewne inteligentne testy głębokości, aby nawet uzyskać wyniki w posortowanej kolejności, ale tutaj jest to mniej ważne.

problem jest, że VertexID oczywiście liczbą całkowitą, od 0 całkowitej wysokości wierzchołków ParticleCount, ale które nie mogą być bezpośrednio stosowane jako wyjście tego modułu wierzchołkowego ma być znormalizowana [-1..1) OpenGL (lub [0..1) w DirectX). Dlatego

Moja vertex shader robi coś takiego:

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

czyli niby działa, ale jakie wartości są właściwie przechowywane do głębokości tekstury związane z obecnym bufora ramki myli mnie. Nie całkiem dostaję różnicy między zmiennopozycyjnym buforem głębi a wersją całkowitą, jeśli nie mogę wyprowadzić rzeczywistych liczb całkowitych i kiedy odczytuję z głębi tekstury wszystko wydaje się być znormalizowane do [0..1] bez względu na format wewnętrzny Ustawiłem (DepthComponent24, 32, 32f).

Czy ktoś może dać mi porady, w jaki sposób uzyskać VertexIDs z tych głębokości tekstury?

Dzięki

+0

„* znormalizowany do [-1..1) w OpenGL (lub [0..1) w DirectX * "1 jest włączony w obu przypadkach. –

+0

Masz rację, lekki niedopatrzenie. Jednak domyślne zachowanie testu głębokości polega na wyczyszczeniu bufora głębi na wartość 1 i porównaniu "mniej niż", dlatego wszystkie punkty o głębokości 1 są usuwane. – Gigo

Odpowiedz

1

Wyjście z tego modułu wierzchołkowego w OpenGL po perspektywicznym podziału jest przymocowane do] [-1,1, co oznacza, gl_Position.z/gl_Position.w musi znajdować się w tym przedziale. Jednak wartość głębokości, która jest faktycznie zapisana w buforze głębi, jest odwzorowywana do zakresu 0..1 przy użyciu bieżących wartości zakresu głębokości (glDepthRange). Domyślnie zakres głębokości 0..1, co przekłada się na

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

Więc w twoim przypadku bufor głębokość ostatecznie zawiera wartości pływaka (gl_VertexID)/ParticleCount, a więc:

vertex_id = depth_buf_value * ParticleCount 
+0

OK, to potwierdza, że ​​to, co próbowałem zrobić, powinno zadziałało, ale tak się nie stało. Postaram się wrócić do tego projektu wkrótce, aby to zadziałało. – Gigo

+0

Jeszcze jedna myśl: co z precyzją? Wewnętrzny format, który jest używany w buforze głębi, trochę mnie myli. Jest obsługiwany jak float, ale przechowywany jako znormalizowany int? Czy ma to wpływ na zakres, który można przedstawić? ParticleCount może równie dobrze być milion lub więcej i muszę być w stanie niezawodnie przywrócić indeks cząstek z bufora głębi. – Gigo

+1

Wartość zmiennoprzecinkowa w zakresie 0..1 jest konwertowana na określony format wewnętrzny. Tę samą precyzję powinieneś otrzymać z 24-bitowym formatem całkowitym i formatem zmiennoprzecinkowym, ponieważ ten ostatni ma 24-bitową mantysę (23 + ukryty bit wiodący), który może być użyty do reprezentowania liczb całkowitych bez utraty bitów. Jednak ponieważ w OpenGL przechodzi przez tę część remapowania, traci się przynajmniej jeden bit tej precyzji.Ale nadal pozostawia 23 bity z> 8 milami odrębnych wartości. – camenomizoratojoakizunewake