• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1uniform sampler2D m_Texture;
2uniform sampler2D m_DepthTexture;
3varying vec2 texCoord;
4
5uniform float m_FocusRange;
6uniform float m_FocusDistance;
7uniform float m_XScale;
8uniform float m_YScale;
9
10vec2 m_NearFar = vec2( 0.1, 1000.0 );
11
12void 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}