// basically a tuned http://tuxedolabs.blogspot.com/2018/05/bokeh-depth-of-field-in-single-pass.html 
#version 450 core

// varying inputs
in vec2 texCoord;

// outputs
out vec4 outColor;

// uniforms
uniform sampler2D t_color;          // original input: rgb - color, a - coc size
uniform sampler2D t_dof;            // previous stage: rgb - color, a - coc size
uniform sampler2D t_depth;

uniform vec2  g_srcResolution;
uniform vec2  g_dstResolution;

// dof uniforms
uniform bool  g_firstPass;          // is this first pass?

uniform vec2  g_pixelSize;          // practically (1.0/g_srcResolution)
uniform float g_startAngle;         // adjust for sample permutation during multiple passes
uniform float g_maxSamples;         // samples in disk
uniform float g_maxRadius;          // max CoC size in pixels (that is, 20.0 covers 40 pixels)

const float GOLDEN_ANGLE = 2.39996323;

const float PI = 3.141592653589793238;

vec2 toUnitDisk(vec2 a) {
	float r, phi;
	if (a.x > -a.y) {
		if (a.x > a.y) {
			r = a.x;
			phi = PI/4 * (a.y/a.x);
		} else {
			r = a.y;
			phi = PI/4 * (2 - (a.x/a.y));
		}
	} else {
		if (a.x < a.y) {
			r = -a.x;
			phi = PI/4 * (4 + (a.y/a.x));
		} else {
			r = -a.y;
			phi = a.y == 0 ? 0 : PI/4 * (6 - (a.x/a.y));
		}
	}
	
	return vec2(r*cos(phi), r*sin(phi));
}


void main() {
    vec4  centerColor = texture(t_color, texCoord);
    float centerDepth = texture(t_depth, texCoord).r;

    float totalSamples = 1.;

    // sample by spiral pattern (colud be precalculated, i think)
    float radius = 0.0;
    for (float i = 1, angle = g_startAngle; i < g_maxSamples; i++, angle += GOLDEN_ANGLE) {
        radius = (sqrt(i) / sqrt(g_maxSamples)) * g_maxRadius;

        vec2  uv = texCoord + vec2(cos(angle), sin(angle)) * g_pixelSize * radius;
        vec4  sampleColor = texture(t_color, uv);
        float sampleDepth = texture(t_depth, uv).r;

        if (sampleDepth > centerDepth)
            sampleColor.a = clamp(sampleColor.a, 0.0, centerColor.a * 2.0);

        float m = smoothstep(radius - 0.5, radius + 0.5, sampleColor.a);
        centerColor.rgb += mix(centerColor.rgb / totalSamples, sampleColor.rgb, m);
        totalSamples += 1.0;
    }
    vec3 totalColor = (centerColor.rgb / totalSamples);
    outColor = vec4(
        g_firstPass ? totalColor : max(totalColor, centerColor.rgb),
        centerColor.a);   // propagate CoC!
}


