Eine chromatische Aberration wird verursacht, wenn ein Objektiv nicht jede Farbe auf den gleichen Brennpunkt fokussieren kann. Eine einfache Möglichkeit, diesen Effekt zu fälschen und ihn als schnellen Postprozess im Vollbildmodus wiederzugeben, besteht darin, jedem Farbkanal in einem Fragment-Shader einen Versatz zuzuweisen.
Durch die Verwendung eines anderen Offsets für jeden Kanal können Sie ein angemessenes Faksimile des gewünschten Effekts erzielen. Ein Beispiel für diese Technik finden Sie hier ; Der Fragment-Shader würde ungefähr so aussehen:
void main () {
// Previously, you'd have rendered your complete scene into a texture
// bound to "fullScreenTexture."
vec4 rValue = texture2D(fullscreenTexture, gl_TexCoords[0] - rOffset);
vec4 gValue = texture2D(fullscreenTexture, gl_TexCoords[0] - gOffset);
vec4 bValue = texture2D(fullscreenTexture, gl_TexCoords[0] - bOffset);
// Combine the offset colors.
gl_FragColor = vec4(rValue.r, gValue.g, bValue.b, 1.0);
}
Dieser einfache Hack berücksichtigt jedoch nicht wirklich die Tatsache, dass chromatische Aberration ein Linseneffekt ist: Um eine bessere Simulation zu erhalten, möchten Sie tatsächlich etwas rendern, das als Linse fungiert. Dies ähnelt dem Rendern von reflektierenden oder refraktiven Objekten. Folglich kann ein typischer Reflexions- / Brechungs-Shader die Basis für die Implementierung der chromatischen Aberration sein.
Normalerweise würde man einen einzigen Brechungs Vektor auf einem Sichtvektor und einige definierte Basis berechnen Brechungsindex unter Verwendung von GLSL der refract Funktion in einem Vertex - Shader:
void main () {
// ...
// RefractionVector is a varying vec3.
// 'ratio' is the ratio of the two indices of refraction.
RefractionVector = refract(incidentVector, normalVector, ratio);
// ...
}
Dann würden Sie diesen Vektor in einem Fragment-Shader verwenden, um eine Würfel-Textur-Suche (in eine Umgebungskarte) durchzuführen. In der Regel wird dies neben einem Reflexionseffekt durchgeführt und unter Verwendung eines berechneten Fresnel-Terms kombiniert .
Um die chromatische Aberration zu simulieren, können Sie im Vertex-Shader drei verschiedene Berechnungen des Brechungsvektors durchführen, die jeweils geringfügig über unterschiedliche Brechungsindizes versetzt sind:
void main () {
// ...
// RefractionVector is a varying vec3, as above.
// 'ratioR,' et cetera, is the ratio of indices of refraction for
// the red, green and blue components respectively.
RedRefractionVector = refract(incidentVector, normalVector, ratioR);
GreenRefractionVector = refract(incidentVector, normalVector, ratioG);
BlueRefractionVector = refract(incidentVector, normalVector, ratioB);
// ...
}
Diese drei verschiedenen Vektoren können verwendet werden, um drei verschiedene Würfelkarten-Lookups durchzuführen, die ähnlich wie in dem einfachen Beispiel gemischt werden können:
void main () {
vec3 color;
color.r = vec3(textureCube(EnvironmentMap, RedRefractionVector)).r;
color.g = vec3(textureCube(EnvironmentMap, GreenRefractionVector)).g;
color.b = vec3(textureCube(EnvironmentMap, BlueRefractionVector)).b;
gl_FragColor = vec4(color, 1.0);
}
Für weitere Details ist das OpenGL Orange Book erhältlich. Es enthält ein Beispiel für die grundlegenden Reflexions- und Brechungseffekte sowie ein Beispiel für den Effekt der chromatischen Aberration.