#include "common.inc"

#ifdef VS

  layout ( location = 0 ) in float4 aPosUV;

	out float2 vUV;
  #if VIGNETTE
    out float2 vClipCoords;
  #endif

  void main()
  {
    gl_Position = float4( aPosUV.xy, 0.f, 1.f );
    float2 uvs = float2( aPosUV.z, 1.f - aPosUV.w );
    vUV = uvs;
    #if VIGNETTE
      vClipCoords = uvs * 2.f - 1.f;
    #endif
  }

#endif //VS

#ifdef PS
  
  layout ( location = 0 ) out float4 FragColor;

  in float2 vUV;

  #if VIGNETTE
    in float2 vClipCoords;
  #endif

  #if BLUR_PASS

  // sDepthTex: for the blur pass, this is not a depth texture, but a regular frame texture
	#if defined(USE_BINDING)
    layout( binding = 0 ) uniform sampler2D sDepthTex;
	#else
	uniform sampler2D sDepthTex;
	#endif

	#if defined(USE_BINDING)
    layout( binding = PSCB1Index, std140 ) uniform PSCB1
	#else
	  layout (std140) uniform PSCB1
	#endif
    {
      float4 viewportSize_InvSize;
    };

    void main()
    {
      float2 offset = 1.5f * viewportSize_InvSize.zw;
      float4 fb0 = texture( sDepthTex, vUV );
      float4 fb1 = texture( sDepthTex, vUV + offset );
      float4 fb2 = texture( sDepthTex, vUV - offset );
      float4 fb3 = texture( sDepthTex, vUV + float2( offset.x, -offset.y ) );
      float4 fb4 = texture( sDepthTex, vUV + float2( -offset.x, offset.y ) );
      
      float4 r = fb0 * 2.f + fb1 + fb2 + fb3 + fb4;

#if MIN_BLUR
      FragColor = min( r / 6.f, fb0  );
#else
      FragColor = ( r / 6.f );
#endif
    }

  #else //!BLUR_PASS
  
	#if defined(USE_BINDING)
    layout( binding = 0 ) uniform sampler2D sDepthTex;
    layout( binding = 1 ) uniform sampler2D sFrameTex;
    layout( binding = 2 ) uniform sampler2D sFrameTex2;
    layout( binding = 3 ) uniform sampler2D sFrameTex4;
    layout( binding = 4 ) uniform sampler2D sFrameTex8;
    layout( binding = 5 ) uniform sampler2D sFrameTex16;
	#else
	uniform sampler2D sDepthTex;
	uniform sampler2D sFrameTex;
	uniform sampler2D sFrameTex2;
	uniform sampler2D sFrameTex4;
	uniform sampler2D sFrameTex8;
	uniform sampler2D sFrameTex16;
	#endif

	#if defined(USE_BINDING)
    layout( binding = PSCB1Index, std140 ) uniform PSCB1
	#else
	layout (std140) uniform PSCB1
	#endif
    {
      float focusHalfRange;
      float falloffRange;
      float focusDist;
      float blurCoeff;
      float4 uProjPlanes;
      float4 uVignetteColRange;
    };

    float getCameraDepth( float depth )
    {
      return uProjPlanes.x / ( uProjPlanes.y - depth * uProjPlanes.z );
    }

    void main()
    {
      float depth = texture( sDepthTex, vUV ).x * 2.0 - 1.0;
      float linDepth = getCameraDepth( depth );
      
      float4 fb = texture( sFrameTex, vUV );
      float4 fb2 = texture( sFrameTex2, vUV );
      float4 fb4 = texture( sFrameTex4, vUV );
      float4 fb8 = texture( sFrameTex8, vUV );
      float4 fb16 = texture( sFrameTex16, vUV );
      
    #if AUTO_FOCUS
      float focusDepth = texture( sDepthTex, float2( 0.5f, 0.5f ) ).x * 2.0 - 1.0; 
      focusDepth = getCameraDepth( focusDepth );
    #else
      float focusDepth = focusDist; 
    #endif

      #if VIGNETTE
        float vignette = saturate( dot( vClipCoords.xy, vClipCoords.xy ) - uVignetteColRange.w );
      #endif

      float distFromFocusDepth = max( 0.f, abs( linDepth - focusDepth ) - focusHalfRange );
      float blurAmt = saturate( distFromFocusDepth / falloffRange ) * 4.f;
      
      float4 r = lerp( fb, fb2, saturate( blurAmt ) * blurCoeff );
      r = lerp( r, fb4, saturate( blurAmt - 1.f ) * blurCoeff );
      r = lerp( r, fb8, saturate( blurAmt - 2.f ) * blurCoeff );
      r = lerp( r, fb16, saturate( blurAmt - 3.f ) * blurCoeff );

      #if VIGNETTE
        r.xyz = lerp( r.xyz, uVignetteColRange.xyz, vignette );
      #endif

      r.a = dot(r.rgb, float3(0.299, 0.587, 0.114));

      FragColor = r;
    }

  #endif //!BLUR_PASS
#endif //PS
