All Downloads are FREE. Search and download functionalities are using the official Maven repository.

Common.MatDefs.Post.DepthOfField.frag Maven / Gradle / Ivy

There is a newer version: 3.7.0-stable
Show newest version
#import "Common/ShaderLib/GLSLCompat.glsllib"
#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;

uniform vec2 g_FrustumNearFar;

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 = g_FrustumNearFar.y / (g_FrustumNearFar.y - g_FrustumNearFar.x);
    float b = g_FrustumNearFar.y * g_FrustumNearFar.x / (g_FrustumNearFar.x - g_FrustumNearFar.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 < BLUR_THRESHOLD ) {
        // 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 += texture2D( m_Texture, vec2(x - 2.0 * xScale, y - 2.0 * yScale) );
    sum += texture2D( m_Texture, vec2(x - 0.0 * xScale, y - 2.0 * yScale) );
    sum += texture2D( m_Texture, vec2(x + 2.0 * xScale, y - 2.0 * yScale) );
    sum += texture2D( m_Texture, vec2(x - 1.0 * xScale, y - 1.0 * yScale) );
    sum += texture2D( m_Texture, vec2(x + 1.0 * xScale, y - 1.0 * yScale) );
    sum += texture2D( m_Texture, vec2(x - 2.0 * xScale, y - 0.0 * yScale) );
    sum += texture2D( m_Texture, vec2(x + 2.0 * xScale, y - 0.0 * yScale) );
    sum += texture2D( m_Texture, vec2(x - 1.0 * xScale, y + 1.0 * yScale) );
    sum += texture2D( m_Texture, vec2(x + 1.0 * xScale, y + 1.0 * yScale) );
    sum += texture2D( m_Texture, vec2(x - 2.0 * xScale, y + 2.0 * yScale) );
    sum += texture2D( m_Texture, vec2(x - 0.0 * xScale, y + 2.0 * yScale) );
    sum += texture2D( m_Texture, vec2(x + 2.0 * xScale, y + 2.0 * yScale) );

    sum = sum / 12.0;

    gl_FragColor = mix( texVal, sum, unfocus );

    #ifdef DEBUG_UNFOCUS
        // Used for debugging the range or user settings
        gl_FragColor.r = unfocus;
        gl_FragColor.g = unfocus;
        gl_FragColor.b = unfocus;
    #endif
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy