¿Cómo implementaría el efecto de la aberración cromática con sombreadores?
¿La resolución del mundo con diferentes distancias de enfoque para cada color resolvería el problema (tal vez con el uso de un solo paso de representación de profundidad)?
¿Cómo implementaría el efecto de la aberración cromática con sombreadores?
¿La resolución del mundo con diferentes distancias de enfoque para cada color resolvería el problema (tal vez con el uso de un solo paso de representación de profundidad)?
Respuestas:
La aberración cromática se produce cuando una lente no puede enfocar todos los colores al mismo punto focal. Una forma sencilla de simular este efecto y representarlo como un postproceso rápido a pantalla completa es aplicar un desplazamiento a cada canal de color en un sombreador de fragmentos.
Al utilizar un desplazamiento diferente para cada canal, puede lograr un facsímil razonable del efecto deseado. Un ejemplo de esta técnica se puede encontrar aquí ; el sombreador de fragmentos se vería así:
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);
}
Sin embargo, este simple truco no tiene en cuenta el hecho de que la aberración cromática es un efecto de lente: para obtener una mejor simulación, en realidad querrás hacer algo para que actúe como la lente. Esto es similar a cómo renderiza objetos que son reflexivos o refractivos. En consecuencia, un típico sombreador de reflexión / refracción puede ser la base para implementar la aberración cromática.
Normalmente, usted calcular un único vector de refracción basada en un vector de vista y algunos se define el índice de refracción , el uso de GLSL refractan función en un vertex shader:
void main () {
// ...
// RefractionVector is a varying vec3.
// 'ratio' is the ratio of the two indices of refraction.
RefractionVector = refract(incidentVector, normalVector, ratio);
// ...
}
Luego usaría ese vector en un sombreador de fragmentos para realizar una búsqueda de textura de cubo (en un mapa de entorno). Por lo general, esto también se realiza junto con un efecto de reflexión, y combinados utilizan un término computado de Fresnel .
Para simular la aberración cromática, puede realizar tres cálculos de vectores de refracción diferentes , cada uno ligeramente compensado a través de diferentes índices de refracción, en el sombreador de vértices:
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);
// ...
}
Esos tres vectores diferentes se pueden usar para realizar tres búsquedas de mapas de cubos diferentes, que se pueden mezclar de forma similar a como se mezclaron los colores en el ejemplo simple:
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);
}
Para obtener más detalles, el OpenGL Orange Book está disponible y contiene un ejemplo de los efectos básicos de reflexión y refracción, así como un ejemplo del efecto de aberración cromática.