Common.MatDefs.Post.DepthOfField.frag Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jme3-effects Show documentation
Show all versions of jme3-effects Show documentation
jMonkeyEngine is a 3-D game engine for adventurous Java developers
#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