Nous allons maintenant voir comment calculer le fog au niveau de chaque pixel. Le principe de calcul est identique
à celui par vertex. La seule différence réside dans la détermination de la distance entre la caméra et le pixel
en cours de traitement. Dans le calcul du fog par pixel, le vertex shader n'intervient pas, tout le calcul s'effectuant dans
le pixel shader.
Il existe en GLSL la variable gl_FragCoord. Cette variable est une variable d'entrée du pixel shader.
gl_FragCoord contient les les coordonnées d'écran du pixel courant. Par exemple, si la fenêtre de la demo
possède une largeur de 1280 pixels, le code suivant:
if(gl_FragCoord.x < 700.0)
{
gl_FragColor = vec4(0.0, 0.5, 0.0, 1.0);
}
else
{
gl_FragColor = mix(gl_Fog.color, finalColor, fogFactor );
}
donnerait l'image suivante:
DEMO_GLSL_Fog_FragCoord.xml
La distance entre la caméra et le pixel courant (valeur de profondeur ou z) est obtenu par la relation suivante:
float z = gl_FragCoord.z / gl_FragCoord.w;
Il est très simple, grâce à cette relation d'afficher une vue du z-buffer du point de vue de la caméra:
float z = 1.0 - (gl_FragCoord.z / gl_FragCoord.w) / 4000.0;
gl_FragColor = vec4(z, z, z, 1.0);
DEMO_GLSL_Fog_DepthBuffer_Visualization.xml
La valeur 4000.0 correspond au plan de clipping lointain (zfar) initialisé dans la demo Demoniak3D.
Ceci dit, revenons à notre calcul du fog. Le code suivant montre comment implémenter le calcul du fog par pixel:
const float LOG2 = 1.442695;
float z = gl_FragCoord.z / gl_FragCoord.w;
float fogFactor = exp2( -gl_Fog.density *
gl_Fog.density *
z *
z *
LOG2 );
fogFactor = clamp(fogFactor, 0.0, 1.0);
gl_FragColor = mix(gl_Fog.color, finalColor, fogFactor );