#version 450 core //#define USE_RANDOM layout( location = 0 ) uniform sampler2D u_Input; layout( location = 1 ) uniform sampler2D u_Depth; layout( location = 2 ) uniform vec4 u_Parameters; layout( location = 3 ) uniform float u_Samples; layout( location = 4 ) uniform vec3 u_ResolutionTime; #define uSharpDist (u_Parameters.x) #define uSharpRange (u_Parameters.y) #define uBlurFalloff (u_Parameters.z) #define uMaxBlur (u_Parameters.w) #define uResolution (u_ResolutionTime.xy) #define uTime (u_ResolutionTime.z) float CoC( float z ) { return uMaxBlur * min( 1 , max( 0 , abs( z - uSharpDist ) - uSharpRange ) / uBlurFalloff ); } layout( location = 0 ) out vec3 o_Color; float hash1( vec2 p ) { p = fract(p * vec2(5.3987, 5.4421)); p += dot(p.yx, p.xy + vec2(21.5351, 14.3137)); return fract(p.x * p.y * 95.4307); } // z: z at UV // coc: blur radius at UV // uv: initial coordinate // blurvec: smudge direction vec3 depthDirectionalBlur( float z , float coc , vec2 uv , vec2 blurvec ) { vec3 sumcol = vec3( 0. ); for ( int i = 0 ; i < u_Samples ; i++ ) { float r = i; #ifdef USE_RANDOM r += hash1( uv + float( i + uTime ) ) - .5; #endif r = r / float( u_Samples - 1 ) - .5; vec2 p = uv + r * coc * blurvec; vec3 smpl = texture( u_Input , p ).xyz; float sz = texture( u_Depth , p ).x; if ( sz < z ) { // if sample is closer consider it's CoC p = uv + r * min( coc , CoC( sz ) ) * blurvec; p = uv + r * CoC( sz ) * blurvec; smpl = texture( u_Input , p ).xyz; } sumcol += smpl; } sumcol /= float( u_Samples ); sumcol = max( sumcol , 0. ); return sumcol; }