GLSL gl FragCoord.z Obliczanie i ustawianie gl FragDepth

Więc mam oszusta (prawdziwa geometria to sześcian, prawdopodobnie obcięty, a geometria oszusta to gąbka Mengera) i muszę obliczyć jego głębokość.

Mogę dość łatwo obliczyć kwotę przesunięcia w przestrzeni świata. Niestety, spędziłem wiele godzin nie zakłócając tym głębi.

Jedyne poprawne wyniki, jakie mogę uzyskać, to kiedy idę:

gl_FragDepth = gl_FragCoord.z

Zasadniczo, muszę wiedzieć, jak gl_FragCoord.z jest obliczane tak, że mogę:

  • Weź transformacja odwrotna z gl_FragCoord.Z do eye space
  • Dodaj perturbację głębi
  • Przekształć tę zaburzoną głębokość z powrotem w tę samą przestrzeń, co oryginalny gl_FragCoord.z.

Przepraszam, jeśli wydaje się to duplikatem pytania; jest tu wiele innych postów, które odnoszą się do podobnych rzeczy. Jednak po wdrożeniu wszystkich z nich żaden nie działa poprawnie. Zamiast próbować wybrać jeden, aby uzyskać pomoc, w tym momencie, proszę o kompletny kod, który robi to. To powinno być tylko kilka linijek.

Author: genpfault, 2012-04-22

2 answers

W przyszłości kod klucza to:

float far=gl_DepthRange.far; float near=gl_DepthRange.near;

vec4 eye_space_pos = gl_ModelViewMatrix * /*something*/
vec4 clip_space_pos = gl_ProjectionMatrix * eye_space_pos;

float ndc_depth = clip_space_pos.z / clip_space_pos.w;

float depth = (((far-near) * ndc_depth) + near + far) / 2.0;
gl_FragDepth = depth;
 29
Author: imallett,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-15 21:11:40

Jeśli chodzi o inne odniesienie, jest to ten sam wzór, który podał imallett, który pracował dla mnie w aplikacji OpenGL 4.0:

vec4 v_clip_coord = modelview_projection * vec4(v_position, 1.0);
float f_ndc_depth = v_clip_coord.z / v_clip_coord.w;
gl_FragDepth = (1.0 - 0.0) * 0.5 * f_ndc_depth + (1.0 + 0.0) * 0.5;

Tutaj modelview_projection jest macierzą 4x4 modelview-projection, a {[2] } jest obiektowo-przestrzenną pozycją renderowanego piksela (w moim przypadku obliczoną przez raymarchera).

Równanie pochodzi z współrzędne okna sekcji tego podręcznika. Zauważ, że w moim kodzie near to 0.0, a far to 1.0, które są domyślne wartości gl_DepthRange. Zauważ, że gl_DepthRange jest a nie tym samym co odległość bliska/dalsza we wzorze na macierz projekcji perspektywy! Jedyną sztuczką jest użycie 0.0 i 1.0 (lub gl_DepthRange na wypadek, gdybyś musiał to zmienić), od godziny zmagam się z innym zakresem głębi - ale to już jest "upieczone" w mojej (perspektywicznej) matrycy projekcyjnej.

Zauważ, że w ten sposób równanie tak naprawdę zawiera tylko jeden mnożnik przez stałą ((far - near) / 2) i pojedynczy dodanie innej stałej ((far + near) / 2). Porównuj to do mnożenia, dodawania i dzielenia (ewentualnie przekonwertowanego do mnożenia przez kompilator optymalizujący), co jest wymagane w kodzie imallett.

 4
Author: the swine,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-01 17:40:18