/*
BSLex (BSL Edit) by LexBoosT
*/

//Settings//
#include "/lib/settings.glsl"

#pragma optimize(on)

//Fragment Shader///////////////////////////////////////////////////////////////////////////////////
#ifdef FSH

//Varyings//
varying vec2 texCoord;

//Uniforms//
uniform float viewWidth, viewHeight, aspectRatio;
uniform float centerDepthSmooth;

uniform mat4 gbufferProjection;

uniform sampler2D colortex0;
uniform sampler2D depthtex1;
uniform sampler2D depthtex0;
uniform mat4 gbufferProjectionInverse;

uniform int isEyeInWater;

//Optifine Constants//
const bool colortex0MipmapEnabled = true;

//Common Variables//

#include "/lib/util/dofOffsets.glsl"

	//Common Functions//

vec3 ChromaAberration(vec3 color)
{
    #ifdef CHROMATIC_ABERRATION
        float chromaOffset = CHROMA_STRENGTH /100.0;
        chromaOffset *= pow(distance(texCoord.st, vec2(1.0)), 2.5);

		color.r = texture2D(colortex0, texCoord.st + vec2(chromaOffset, 0.0)).r;
		color.g = texture2D(colortex0, texCoord.st).g;
		color.b = texture2D(colortex0, texCoord.st - vec2(chromaOffset, 0.0)).b;

    #endif
    return color;
}


vec3 DepthOfField(vec3 color, float z){
	
#ifdef NETHER
    float DISTANCE_BLUR_STRENGTH = NETHER_DISTANCE_BLUR_STRENGTH;
	float DOF_STRENGTH = NETHER_DOF_STRENGTH;
#else
    float DISTANCE_BLUR_STRENGTH = OVERWORLD_DISTANCE_BLUR_STRENGTH;
	float DOF_STRENGTH = OVERWORLD_DOF_STRENGTH;
#endif

    vec3 dof = vec3(0.0);
    float hand = float(z < 0.56);
	float fovScale = gbufferProjection[1][1] / 1.25;
    #ifdef DISTANCE_BLUR
    float z0 = texture2D(depthtex0, texCoord.xy).r;
    vec4 screenPos = vec4(texCoord.x, texCoord.y, z0, 1.0);
    vec4 viewPos = gbufferProjectionInverse * (screenPos * 2.0 - 1.0);
    viewPos /= viewPos.w;
    
    float coc1 = max(min(length(viewPos) * 0.001, 0.1) * DISTANCE_BLUR_STRENGTH / 256, 0.001);
    #else
    float coc1 = 0;
    #endif

    #ifdef DOF
    float coc2 = max(abs(z - centerDepthSmooth) * DOF_STRENGTH - 0.001, 0.0);
    #else
    float coc2 = 0;
    #endif
    float coc = max(coc1,coc2);
		#ifdef FLOU_EAU
		if (float(isEyeInWater) > 0.9) coc = max(FACTEUR_FLOU_EAU / 2 ,coc);
		#endif
    coc = coc / sqrt(coc * coc + 0.1);	
    float chromaOffset = CHROMA_STRENGTH /100.0;
    chromaOffset *= coc;
    if (coc * 0.5 > 1.0 / max(viewWidth, viewHeight) && hand < 0.5){
		#if BLUR_QUALITY == 1
		int nbOffsets = 30;
		#endif
		#if BLUR_QUALITY == 2
		int nbOffsets = 50;
		#endif
		#if BLUR_QUALITY == 3
		int nbOffsets = 75;
		#endif
		#if BLUR_QUALITY == 4
		int nbOffsets = 209;
		#endif
		#if BLUR_QUALITY == 5
		int nbOffsets = 6;
		#endif
		#if BLUR_QUALITY == 6
		int nbOffsets = 60;
		#endif


        for(int i = 0; i < nbOffsets; i++) {
			vec2 offset = dofOffsets[i] * coc * 0.015 * fovScale * vec2(1.0 / aspectRatio, 1.0);
            float lod = log2(viewHeight * aspectRatio * coc * fovScale / 320.0);
            #ifdef CHROMATIC_ABERRATION
            dof.r += texture2DLod(colortex0, texCoord + offset+vec2(chromaOffset,0.0), lod).r;
            dof.g += texture2DLod(colortex0, texCoord + offset, lod).g;
            dof.b += texture2DLod(colortex0, texCoord + offset-vec2(chromaOffset,0.0), lod).b;
            #else
            dof += texture2DLod(colortex0, texCoord + offset, lod).rgb;
            #endif
        }
        dof /= nbOffsets;
    }
    else dof = color;
    return dof;
}
	
	//Includes//
	#ifdef BLACK_OUTLINE
	#include "/lib/outline/outlineOffset.glsl"
	#include "/lib/outline/depthOutline.glsl"
	#endif
	
	
	void main(){
		vec3 color = texture2D(colortex0,texCoord).rgb;
		

		float z = texture2D(depthtex1, texCoord.st).x;
		
		#ifdef BLACK_OUTLINE
		DepthOutline(z);
		#endif

		if(z > 0.56){
		color = ChromaAberration(color);
		}

		color = DepthOfField(color, z);

		
		/*DRAWBUFFERS:0*/
		gl_FragData[0]=vec4(color,1.);
	}
	
	#endif
	
	//Vertex Shader/////////////////////////////////////////////////////////////////////////////////////
	#ifdef VSH
	
	//Varyings//
	varying vec2 texCoord;
	
	//Program//
	void main(){
		texCoord=gl_MultiTexCoord0.xy;
		
		gl_Position=ftransform();
	}
	
	#endif