|
@@ -0,0 +1,91 @@
|
|
|
+#import "Common/ShaderLib/MultiSample.glsllib"
|
|
|
+
|
|
|
+uniform COLORTEXTURE m_Texture;
|
|
|
+uniform DEPTHTEXTURE m_DepthTexture;
|
|
|
+varying vec2 texCoord;
|
|
|
+
|
|
|
+uniform float m_FocusRange;
|
|
|
+uniform float m_FocusDistance;
|
|
|
+uniform float m_XScale;
|
|
|
+uniform float m_YScale;
|
|
|
+
|
|
|
+vec2 m_NearFar = vec2( 0.1, 1000.0 );
|
|
|
+
|
|
|
+void main() {
|
|
|
+
|
|
|
+ vec4 texVal = getColor( m_Texture, texCoord );
|
|
|
+
|
|
|
+ float zBuffer = getDepth( m_DepthTexture, texCoord ).r;
|
|
|
+
|
|
|
+ //
|
|
|
+ // z_buffer_value = a + b / z;
|
|
|
+ //
|
|
|
+ // Where:
|
|
|
+ // a = zFar / ( zFar - zNear )
|
|
|
+ // b = zFar * zNear / ( zNear - zFar )
|
|
|
+ // z = distance from the eye to the object
|
|
|
+ //
|
|
|
+ // Which means:
|
|
|
+ // zb - a = b / z;
|
|
|
+ // z * (zb - a) = b
|
|
|
+ // z = b / (zb - a)
|
|
|
+ //
|
|
|
+ float a = m_NearFar.y / (m_NearFar.y - m_NearFar.x);
|
|
|
+ float b = m_NearFar.y * m_NearFar.x / (m_NearFar.x - m_NearFar.y);
|
|
|
+ float z = b / (zBuffer - a);
|
|
|
+
|
|
|
+ // Above could be the same for any depth-based filter
|
|
|
+
|
|
|
+ // We want to be purely focused right at
|
|
|
+ // m_FocusDistance and be purely unfocused
|
|
|
+ // at +/- m_FocusRange to either side of that.
|
|
|
+ float unfocus = min( 1.0, abs( z - m_FocusDistance ) / m_FocusRange );
|
|
|
+
|
|
|
+ if( unfocus < 0.2 ) {
|
|
|
+ // If we are mostly in focus then don't bother with the
|
|
|
+ // convolution filter
|
|
|
+ gl_FragColor = texVal;
|
|
|
+ } else {
|
|
|
+ // Perform a wide convolution filter and we scatter it
|
|
|
+ // a bit to avoid some texture look-ups. Instead of
|
|
|
+ // a full 5x5 (25-1 lookups) we'll skip every other one
|
|
|
+ // to only perform 12.
|
|
|
+ // 1 0 1 0 1
|
|
|
+ // 0 1 0 1 0
|
|
|
+ // 1 0 x 0 1
|
|
|
+ // 0 1 0 1 0
|
|
|
+ // 1 0 1 0 1
|
|
|
+ //
|
|
|
+ // You can get away with 8 just around the outside but
|
|
|
+ // it looks more jittery to me.
|
|
|
+
|
|
|
+ vec4 sum = vec4(0.0);
|
|
|
+
|
|
|
+ float x = texCoord.x;
|
|
|
+ float y = texCoord.y;
|
|
|
+
|
|
|
+ float xScale = m_XScale;
|
|
|
+ float yScale = m_YScale;
|
|
|
+
|
|
|
+ // In order from lower left to right, depending on how you look at it
|
|
|
+ sum += getColor( m_Texture, vec2(x - 2.0 * xScale, y - 2.0 * yScale) );
|
|
|
+ sum += getColor( m_Texture, vec2(x - 0.0 * xScale, y - 2.0 * yScale) );
|
|
|
+ sum += getColor( m_Texture, vec2(x + 2.0 * xScale, y - 2.0 * yScale) );
|
|
|
+ sum += getColor( m_Texture, vec2(x - 1.0 * xScale, y - 1.0 * yScale) );
|
|
|
+ sum += getColor( m_Texture, vec2(x + 1.0 * xScale, y - 1.0 * yScale) );
|
|
|
+ sum += getColor( m_Texture, vec2(x - 2.0 * xScale, y - 0.0 * yScale) );
|
|
|
+ sum += getColor( m_Texture, vec2(x + 2.0 * xScale, y - 0.0 * yScale) );
|
|
|
+ sum += getColor( m_Texture, vec2(x - 1.0 * xScale, y + 1.0 * yScale) );
|
|
|
+ sum += getColor( m_Texture, vec2(x + 1.0 * xScale, y + 1.0 * yScale) );
|
|
|
+ sum += getColor( m_Texture, vec2(x - 2.0 * xScale, y + 2.0 * yScale) );
|
|
|
+ sum += getColor( m_Texture, vec2(x - 0.0 * xScale, y + 2.0 * yScale) );
|
|
|
+ sum += getColor( m_Texture, vec2(x + 2.0 * xScale, y + 2.0 * yScale) );
|
|
|
+
|
|
|
+ sum = sum / 12.0;
|
|
|
+
|
|
|
+ gl_FragColor = mix( texVal, sum, unfocus );
|
|
|
+
|
|
|
+ // I used this for debugging the range
|
|
|
+ // gl_FragColor.r = unfocus;
|
|
|
+ }
|
|
|
+}
|