opengl - descargar - GLSL: ¿Cómo obtener la posición mundial de pixel x, y, z?
opengl shader descargar (4)
Quiero ajustar los colores dependiendo de la posición xyz que estén en el mundo.
Intenté esto en mi fragmentador de fragmentos:
varying vec4 verpos;
void main(){
vec4 c;
c.x = verpos.x;
c.y = verpos.y;
c.z = verpos.z;
c.w = 1.0;
gl_FragColor = c;
}
pero parece que los colores cambian dependiendo del ángulo / posición de mi cámara, ¿cómo hago que los coords sean independientes de la posición / ángulo de mi cámara?
Aquí está mi sombreador de vértices:
varying vec4 verpos;
void main(){
gl_Position = ftransform();
verpos = gl_ModelViewMatrix*gl_Vertex;
}
Edit2: título cambiado, ¡así que quiero coords mundiales, no coords de pantalla!
Edit3: agregué mi código completo
Debe pasar la matriz Mundo / Modelo como un uniforme al sombreador de vértices, y luego multiplíquelo por la posición del vértice y envíelo como un sombreador de fragmentos al fragmento:
/*Vertex Shader*/
layout (location = 0) in vec3 Position
uniform mat4 World;
uniform mat4 WVP;
//World FragPos
out vec4 FragPos;
void main()
{
FragPos = World * vec4(Position, 1.0);
gl_Position = WVP * vec4(Position, 1.0);
}
/*Fragment Shader*/
layout (location = 0) out vec4 Color;
...
in vec4 FragPos
void main()
{
Color = FragPos;
}
En vertex shader tienes gl_Vertex (o algo más si no usas pipeline fijo) que es la posición de un vértice en las coordenadas del modelo. Multiplique la matriz del modelo por gl_Vertex y obtendrá la posición del vértice en las coordenadas mundiales. Asigne esto a una variable variable, y luego lea su valor en el sombreador de fragmentos y obtendrá la posición del fragmento en coordenadas mundiales.
Ahora el problema en esto es que no necesariamente tiene una matriz de modelo si usa la matriz de vista de modelo predeterminada de OpenGL, que es una combinación de matrices de modelo y de vista. Normalmente resuelvo este problema teniendo dos matrices separadas en lugar de solo una matriz modelview:
- matriz modelo (coordenadas del modelo de mapas a coordenadas mundiales), y
- matriz de vista (asigna las coordenadas del mundo a las coordenadas de la cámara).
Así que simplemente pase dos matrices diferentes a su vertex shader por separado. Puedes hacer esto definiendo
uniform mat4 view_matrix;
uniform mat4 model_matrix;
Al comienzo de tu sombreador de vértices. Y luego, en lugar de ftransform (), diga:
gl_Position = gl_ProjectionMatrix * view_matrix * model_matrix * gl_Vertex;
En el programa principal, debe escribir valores en estas dos nuevas matrices. Primero, para obtener la matriz de vistas, realice las transformaciones de la cámara con glLoadIdentity (), glTranslate (), glRotate () o gluLookAt () o lo que prefiera como lo haría normalmente, pero luego llame a glGetFloatv (GL_MODELVIEW_MATRIX, & array); para obtener los datos de la matriz en una matriz. Y en segundo lugar, de manera similar, para obtener la matriz del modelo, también llame a glLoadIdentity (); y hacer las transformaciones del objeto con glTranslate (), glRotate (), glScale () etc. y finalmente llamar a glGetFloatv (GL_MODELVIEW_MATRIX, & array); para obtener los datos de la matriz de OpenGL, para que pueda enviarlos a su vertex shader. Tenga en cuenta especialmente que debe llamar a glLoadIdentity () antes de comenzar a transformar el objeto. Normalmente, primero se transformaría la cámara y luego se transformaría el objeto, lo que daría como resultado una matriz que realiza las funciones de vista y modelo. Pero debido a que está utilizando matrices separadas, debe restablecer la matriz después de las transformaciones de la cámara con glLoadIdentity ().
gl_FragCoord son las coordenadas de píxel y no las coordenadas mundiales.
La forma más fácil es bajar la posición mundial desde el sombreador de vértices a través de una variable variable.
Sin embargo, si realmente debe reconstruirlo desde gl_FragCoord
, la única forma de hacerlo es invertir todos los pasos que llevaron a las coordenadas gl_FragCoord. Consulte las especificaciones de OpenGL, si realmente tiene que hacer esto, porque será necesaria una comprensión profunda de las transformaciones.
O bien, podría dividir la coordenada z por la coordenada w, lo que esencialmente deshace la proyección en perspectiva; dándote tus coordenadas mundiales originales.
es decir.
depth = gl_FragCoord.z / gl_FragCoord.w;
Por supuesto, esto solo funcionará para coordenadas no recortadas ..
¿Pero a quién le importan los recortados de todos modos?