Home | History | Annotate | Download | only in Post
      1 uniform sampler2D m_Texture;
      2 uniform sampler2D m_DepthTexture;
      3 varying vec2 texCoord;
      4 
      5 uniform float m_FocusRange;
      6 uniform float m_FocusDistance;
      7 uniform float m_XScale;
      8 uniform float m_YScale;
      9 
     10 vec2 m_NearFar = vec2( 0.1, 1000.0 );
     11 
     12 void main() {
     13 
     14     vec4 texVal = texture2D( m_Texture, texCoord );
     15 
     16     float zBuffer = texture2D( m_DepthTexture, texCoord ).r;
     17 
     18     //
     19     // z_buffer_value = a + b / z;
     20     //
     21     // Where:
     22     //  a = zFar / ( zFar - zNear )
     23     //  b = zFar * zNear / ( zNear - zFar )
     24     //  z = distance from the eye to the object
     25     //
     26     // Which means:
     27     // zb - a = b / z;
     28     // z * (zb - a) = b
     29     // z = b / (zb - a)
     30     //
     31     float a = m_NearFar.y / (m_NearFar.y - m_NearFar.x);
     32     float b = m_NearFar.y * m_NearFar.x / (m_NearFar.x - m_NearFar.y);
     33     float z = b / (zBuffer - a);
     34 
     35     // Above could be the same for any depth-based filter
     36 
     37     // We want to be purely focused right at
     38     // m_FocusDistance and be purely unfocused
     39     // at +/- m_FocusRange to either side of that.
     40     float unfocus = min( 1.0, abs( z - m_FocusDistance ) / m_FocusRange );
     41 
     42     if( unfocus < 0.2 ) {
     43         // If we are mostly in focus then don't bother with the
     44         // convolution filter
     45         gl_FragColor = texVal;
     46     } else {
     47     // Perform a wide convolution filter and we scatter it
     48     // a bit to avoid some texture look-ups.  Instead of
     49     // a full 5x5 (25-1 lookups) we'll skip every other one
     50     // to only perform 12.
     51     // 1  0  1  0  1
     52     // 0  1  0  1  0
     53     // 1  0  x  0  1
     54     // 0  1  0  1  0
     55     // 1  0  1  0  1
     56     //
     57     // You can get away with 8 just around the outside but
     58     // it looks more jittery to me.
     59 
     60     vec4 sum = vec4(0.0);
     61 
     62     float x = texCoord.x;
     63     float y = texCoord.y;
     64 
     65     float xScale = m_XScale;
     66     float yScale = m_YScale;
     67 
     68     // In order from lower left to right, depending on how you look at it
     69     sum += texture2D( m_Texture, vec2(x - 2.0 * xScale, y - 2.0 * yScale) );
     70     sum += texture2D( m_Texture, vec2(x - 0.0 * xScale, y - 2.0 * yScale) );
     71     sum += texture2D( m_Texture, vec2(x + 2.0 * xScale, y - 2.0 * yScale) );
     72     sum += texture2D( m_Texture, vec2(x - 1.0 * xScale, y - 1.0 * yScale) );
     73     sum += texture2D( m_Texture, vec2(x + 1.0 * xScale, y - 1.0 * yScale) );
     74     sum += texture2D( m_Texture, vec2(x - 2.0 * xScale, y - 0.0 * yScale) );
     75     sum += texture2D( m_Texture, vec2(x + 2.0 * xScale, y - 0.0 * yScale) );
     76     sum += texture2D( m_Texture, vec2(x - 1.0 * xScale, y + 1.0 * yScale) );
     77     sum += texture2D( m_Texture, vec2(x + 1.0 * xScale, y + 1.0 * yScale) );
     78     sum += texture2D( m_Texture, vec2(x - 2.0 * xScale, y + 2.0 * yScale) );
     79     sum += texture2D( m_Texture, vec2(x - 0.0 * xScale, y + 2.0 * yScale) );
     80     sum += texture2D( m_Texture, vec2(x + 2.0 * xScale, y + 2.0 * yScale) );
     81 
     82     sum = sum / 12.0;
     83 
     84     gl_FragColor = mix( texVal, sum, unfocus );
     85 
     86     // I used this for debugging the range
     87    // gl_FragColor.r = unfocus;
     88 }
     89 }