2009-08-17 22 views
14

Ok, en mi sombreador de fragmentos GLSL quiero poder calcular la distancia del fragmento desde una línea particular en el espacio.Cómo calcular gl_FragCoord en glsl

El resultado de esto es que estoy primero tratando de utilizar un conjunto vec2 variando en mi vertex shader para reflejar lo que termina en gl_FragCoord:

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

Ahora en el fragment shader espero:

gl_FragCoord.xy==fake_frag_coord 

Pero no es así. ¿Qué operación hace la tubería en gl_Position para convertirla en gl_FragCoord que no hago en fake_frag_coord?

Respuesta

11

gl_FragCoord son las coordenadas de la pantalla, por lo que necesitaría tener información sobre el tamaño de la pantalla y tal como se produce en función de la posición. El fake_frag_coord que ha producido corresponderá a un punto de la pantalla en las coordenadas del dispositivo normalizado, creo (-1 a 1). Entonces, si tuviera que multiplicar por la mitad el tamaño de la pantalla en una dimensión particular, y luego agregar ese tamaño, obtendría píxeles de pantalla reales.

+1

Estaba equivocado acerca de que estuviera equivocado, pero tiene razón al usar gl_ModelViewProjectionMatrix * gl_Vertex que podría presentar errores de cálculo. – karx11erx

+2

Nitpick: eso realmente te dará coordenadas de espacio de clip en lugar de coordenadas de dispositivo normalizadas, ya que no estás realizando la división de perspectiva que ocurre durante el proceso de rasterización (entre el sombreador de vértices y el sombreador de fragmentos). http://www.glprogramming.com/red/chapter03.html#name1 – Pike65

+0

@ Pike65 Eso no es solo una pequeñez, debería dar como resultado valores completamente diferentes para una proyección en perspectiva. –

0

El problema que tiene es que gl_ModelViewProjectionMatrix * gl_Vertex calculado en un sombreado no es siempre lo que produce la tubería de función fija. Para obtener resultados idénticos, haga fake_frag_coord = ftransform().

Editar:

Y luego escalar con sus dimensiones de la pantalla.

+0

ftransform produce la posición, no el fragcoord. La pregunta no es cómo obtener el puesto. –

+0

Mi respuesta no fue completamente incorrecta. Necesita escalar fake_frag_coord con las dimensiones de su pantalla, pero puede obtener diferentes resultados dependiendo de si usa fake_frag_coord = gl_ModelViewProjectionMatrix * gl_Vertex o = ftransform(). – karx11erx

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

fake_frag_coord=(gl_ModelViewMatrix * gl_Vertex).xy 
0

Ojalá tuviera más representante, así que también podría criticar. Esto es lo que sé. OpenGL realiza el Divide-By-W automáticamente para usted, de modo que cuando llega una posición en un sombreador de fragmentos, ya está en coordenadas NDC, y para entonces W será 1.0, el único momento en que necesita dividir por W es si desea hacer las mismas operaciones matemáticas en el lado de la CPU, y obtener los mismos resultados, O, si por alguna razón impar, quería obtener las coordenadas NDC dentro de su sombreado de vértices.

+1

'gl_FragCoord' es ** no ** en NDC. Está en las coordenadas de la ventana. –