Sto scrivendo uno shader GLSL che simula l'aberrazione cromatica per oggetti semplici. Sono compatibile con OpenGL 2.0, quindi utilizzo lo stack matrix OpenGL integrato. Questa è la semplice vertex:Riflessione/rifrazione con aberrazione cromatica - correzione dell'occhio
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();
}
Il cameraPos
uniforme è la posizione della fotocamera nello spazio modello, come si potrebbe immaginare. Qui è lo shader frammento:
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);
}
Il environment
è una mappa del cubo che è resa dal vivo l'ambiente del oggetto disegnato.
In circostanze normali, lo shader comporta (Credo) come previsto, ottenendo questo risultato:
Tuttavia, quando la telecamera viene ruotata di 180 ° attorno al suo bersaglio, in modo che ora punta a l'oggetto dall'altro lato, l'immagine rifratto/riflessa deformarlo in questo modo (Ciò avviene gradualmente per angoli tra 0 e 180 gradi, ovviamente):
Manufatti simili appaiono quando la fotocamera viene abbassata/sollevata; sembra solo comportarsi correttamente al 100% quando la telecamera è direttamente sopra l'oggetto target (puntando verso Z negativo, in questo caso).
Non riesco a capire quale trasformazione nello shader è responsabile di questa immagine deformata, ma dovrebbe essere qualcosa di ovvio in relazione a come viene gestito cameraPos
. In che modo l'immagine si deforma in questo modo?
Questo era! Ho dovuto anche sostituire il 'gl_NormalMatrix' di' mat3 (modelMatrix) 'per ovvi motivi. Non mi ha mai colpito il fatto che dovrei considerare lo spazio della variabile 'position', sembrava in qualche modo banalmente corretto. Grazie! – dflemstr