Estoy escribiendo un sombreador GLSL que simula la aberración cromática para objetos simples. Me mantengo compatible con OpenGL 2.0, así que uso la pila de matriz OpenGL integrada. Este es el simple vertex shader:Reflexión/refracción con aberración cromática - corrección de ojos
uniform vec3 cameraPos;
varying vec3 incident;
varying vec3 normal;
void main(void) {
vec4 position = gl_ModelViewMatrix * gl_Vertex;
incident = position.xyz/position.w - cameraPos;
normal = gl_NormalMatrix * gl_Normal;
gl_Position = ftransform();
}
El cameraPos
uniforme es la posición de la cámara en el espacio modelo, como uno podría imaginar. Aquí está el fragment shader:
const float etaR = 1.14;
const float etaG = 1.12;
const float etaB = 1.10;
const float fresnelPower = 2.0;
const float F = ((1.0 - etaG) * (1.0 - etaG))/((1.0 + etaG) * (1.0 + etaG));
uniform samplerCube environment;
varying vec3 incident;
varying vec3 normal;
void main(void) {
vec3 i = normalize(incident);
vec3 n = normalize(normal);
float ratio = F + (1.0 - F) * pow(1.0 - dot(-i, n), fresnelPower);
vec3 refractR = vec3(gl_TextureMatrix[0] * vec4(refract(i, n, etaR), 1.0));
vec3 refractG = vec3(gl_TextureMatrix[0] * vec4(refract(i, n, etaG), 1.0));
vec3 refractB = vec3(gl_TextureMatrix[0] * vec4(refract(i, n, etaB), 1.0));
vec3 reflectDir = vec3(gl_TextureMatrix[0] * vec4(reflect(i, n), 1.0));
vec4 refractColor;
refractColor.ra = textureCube(environment, refractR).ra;
refractColor.g = textureCube(environment, refractG).g;
refractColor.b = textureCube(environment, refractB).b;
vec4 reflectColor;
reflectColor = textureCube(environment, reflectDir);
vec3 combinedColor = mix(refractColor, reflectColor, ratio);
gl_FragColor = vec4(combinedColor, 1.0);
}
El environment
es un mapa de cubo que se representa en vivo desde el entorno del objeto dibujado.
En circunstancias normales, el sombreado se comporta (creo), como se esperaba, dando el siguiente resultado:
Sin embargo, cuando la cámara se gira 180 grados alrededor de su objetivo, de modo que ahora apunta a el objeto desde el otro lado, la imagen refractada/reflejada se combado como tal (Esto ocurre gradualmente para ángulos entre 0 y 180 grados, por supuesto):
Aparecen artefactos similares cuando la cámara se baja/levanta; solo parece comportarse al 100% correctamente cuando la cámara está directamente sobre el objeto objetivo (apuntando hacia la Z negativa, en este caso).
Tengo problemas para determinar qué transformación en el sombreador es responsable de esta imagen deformada, pero debería ser algo obvio relacionado con cómo se maneja cameraPos
. ¿Qué está causando que la imagen se combe de esta manera?
¡Esto fue todo! También tuve que reemplazar el 'gl_NormalMatrix' por' mat3 (modelMatrix) 'por razones obvias. Simplemente nunca me di cuenta de que debería considerar el espacio de la variable 'position', parecía ser trivialmente correcto de alguna manera. ¡Gracias! – dflemstr