2009-08-17 7 views
14

Ok, w moim shaderze fragmentów GLSL chcę być w stanie obliczyć odległość fragmentu od konkretnej linii w przestrzeni.Jak obliczyć gl_FragCoord w glsl

Wynikiem tego jest to, że ja najpierw próbuje użyć zmienną zestaw vec2 w moim vertex shader do lustra, co kończy się w gl_FragCoord:

varying vec2 fake_frag_coord; 
//in vertex shader: 
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; 
fake_frag_coord=(gl_ModelViewProjectionMatrix * gl_Vertex).xy; 

Teraz w shadera fragmentów Spodziewam:

gl_FragCoord.xy==fake_frag_coord 

Ale tak się nie dzieje. Jaką operację wykonuje potok na gl_Position, aby przekształcić go w gl_FragCoord, którego zaniedbuję w przypadku fake_frag_coord?

Odpowiedz

11

gl_FragCoord jest współrzędnych ekranu, więc musisz mieć informacje o rozmiarze ekranu i takie, aby go wyprodukować w oparciu o pozycję. Wygenerowany przez ciebie fake_frag_coord będzie odpowiadał punktowi na ekranie w znormalizowanych współrzędnych urządzenia, które myślę (-1 do 1). Jeśli więc pomnożysz o połowę rozmiaru ekranu w danym wymiarze, a następnie dodasz ten rozmiar, otrzymasz rzeczywiste piksele ekranu.

+1

Myliłem się, że się mylisz, ale masz rację, używając gl_ModelViewProjectionMatrix * gl_Vertex potencjalnie wprowadzającego błędy obliczeniowe. – karx11erx

+2

Nitpick: to faktycznie da współrzędne przestrzeni klipu zamiast znormalizowanych współrzędnych urządzenia, ponieważ nie wykonujesz podziału perspektywy, który ma miejsce podczas procesu rasteryzacji (między modułem cieniującym wierzchołka a modułem cieniującym fragment). http://www.glprogramming.com/red/chapter03.html#name1 – Pike65

+0

@ Pike65 To nie tylko dziurkacz, powinno to skutkować zupełnie innymi wartościami dla projekcji perspektywicznej. –

0

Problem polega na tym, że gl_ModelViewProjectionMatrix * gl_Vertex obliczony w module cieniującym nie zawsze jest zgodny z wydajnością potokowej funkcji. Aby uzyskać identyczne wyniki, wykonaj fake_frag_coord = ftransform().

Edytuj:

Następnie skaluj go za pomocą wymiarów ekranu.

+0

ftransform tworzy pozycję, a nie fragcoord. Pytanie nie pyta, jak zdobyć pozycję. –

+0

Moja odpowiedź nie była całkowicie błędna. Musisz skalować fake_frag_coord z wymiarami ekranu, ale możesz uzyskać różne wyniki w zależności od tego, czy używasz fake_frag_coord = gl_ModelViewProjectionMatrix * gl_Vertex lub = ftransform(). – karx11erx

-2
varying vec2 fake_frag_coord; 
//in vertex shader: 

fake_frag_coord=(gl_ModelViewMatrix * gl_Vertex).xy 
0

Żałuję, że nie miałem więcej przedstawiciela, więc mogłem też wytrzepać. Oto, co wiem. OpenGL automatycznie wykonuje Divide-By-W dla ciebie, więc zanim nadejdzie pozycja w shaderze fragmentu, jest już we współrzędnych NDC, a wtedy W będzie 1.0, jedyny czas, który musisz podzielić przez W, to chcesz wykonać tę samą matematykę po stronie procesora, i uzyskać takie same wyniki, LUB, jeśli z jakiegoś dziwnego powodu, chciałeś uzyskać współrzędne NDC w twoim vertex shader.

+1

'gl_FragCoord' jest ** nie ** w NDC. Jest we współrzędnych okna. –