Fogging

Fogging is the phenomenon in which a distant object looks hazy. We will explore linear fog here, although there exist other fog calculations such as the exponential fog.

The fog factor describes how clearly we can see the object. When it is 1.0, the object can be seen completely. When it is 0.0, the object cannot be seen at all.

<fog factor> = (<end point> - <distance from the eye point) / (<end point> - <starting point>)
where
<starting point>   <=  <distance from the eye point>   <=  <end point>

The lower tip of the triangle is farther away, and is thus more obscured.
RESETRUNFULL
<!DOCTYPE html><html>
<head>
<script src="/shared/webgl-library.js"></script>
<script id="vs" type="x-shader/x-vertex">
   attribute vec4 p;
   attribute vec4 c;
   uniform mat4 modelMatrix;
   uniform mat4 viewMatrix;
   uniform mat4 projectionMatrix;
   uniform vec4 eyePosition;
   varying vec4 color;
   varying float dist;
   void main() {
      gl_Position = projectionMatrix*viewMatrix*modelMatrix*p;
      color = c;
      dist = distance(modelMatrix * p, eyePosition);
   }
</script>
<script id="fs" type="x-shader/x-fragment">
   #ifdef GL_ES
   precision mediump float;
   #endif
   uniform vec3 fogColor;
   uniform vec2 fogDistance;
   varying vec4 color;
   varying float dist;
   void main() {
      float fogFactor = clamp((fogDistance.y-dist)/
                              (fogDistance.y-fogDistance.x),0.0,1.0);
      vec3 finalColor = mix(fogColor, vec3(color), fogFactor);
      gl_FragColor = vec4(finalColor, color.a);
   }
</script>
<script>
function main() {
   var canvas = document.getElementById('myCanvas');
   var gl = canvas.getContext('webgl');
   initShaders(gl, 'vs', 'fs');
   var fogColor = new Float32Array([0.0,0.0,0.0]);
   var fogDistance = new Float32Array([3,8]);
   var eye = new Float32Array([0,0,3,1.0]);
   var epL = gl.getUniformLocation(gl.program, 'eyePosition');
   var fcL = gl.getUniformLocation(gl.program, 'fogColor');
   var fdL = gl.getUniformLocation(gl.program, 'fogDistance');
   gl.uniform3fv(fcL, fogColor);
   gl.uniform2fv(fdL, fogDistance);
   gl.uniform4fv(epL, eye);
   var mmL = gl.getUniformLocation(gl.program, 'modelMatrix');
   var vmL = gl.getUniformLocation(gl.program, 'viewMatrix');
   var pmL = gl.getUniformLocation(gl.program, 'projectionMatrix');
   var mm = new Matrix4();
   var vm = new Matrix4();
   var pm = new Matrix4();
   mm.scale(1, 1.5, 1);
   pm.perspective(30, canvas.width/canvas.height, 1, 10);
   vm.lookAt(eye[0], eye[1], eye[2], 0, 0, 0, 0, 1, 0);
   gl.uniformMatrix4fv(mmL, false, new Float32Array(mm.entries));
   gl.uniformMatrix4fv(vmL, false, new Float32Array(vm.entries));
   gl.uniformMatrix4fv(pmL, false, new Float32Array(pm.entries));
   gl.clearColor(0, 0, 0, 1);
   gl.clear(gl.COLOR_BUFFER_BIT);
   draw_colored_triangle(gl);}function draw_colored_triangle(gl){
   var points=new Array();
   var vc= new Float32Array([ 0.0,-0.5,-5.0,  1.0, 1.0, 1.0,
                             -0.5, 0.5, 0.0,  1.0, 1.0, 1.0,
                              0.5, 0.5, 0.0,  1.0, 1.0, 1.0]);
   var ESIZE=vc.BYTES_PER_ELEMENT;
   var b=gl.createBuffer();
   gl.bindBuffer(gl.ARRAY_BUFFER,b);
   gl.bufferData(gl.ARRAY_BUFFER,vc,gl.STATIC_DRAW);
   pL=gl.getAttribLocation(gl.program,'p');
   gl.vertexAttribPointer(pL,3,gl.FLOAT,false,ESIZE*6,0);
   gl.enableVertexAttribArray(pL);
   cL=gl.getAttribLocation(gl.program,'c');
   gl.vertexAttribPointer(cL,3,gl.FLOAT,false,ESIZE*6, ESIZE*3);
   gl.enableVertexAttribArray(cL);
   gl.clearColor(0.0,0.0,0.0,1.0);
   gl.clear(gl.COLOR_BUFFER_BIT);
   gl.drawArrays(gl.TRIANGLES,0,3);
}
</script>
</head>
<body onload="main()">
   <canvas id="myCanvas" width="500" height="500"></canvas>
</body>
</html>