﻿#ifndef SSR_BLUR
#define SSR_BLUR

	// Copyright 2021 Kronnect - All Rights Reserved.
    TEXTURE2D_X(_MainTex);
    float4 _MainTex_TexelSize;
    TEXTURE2D_X(_RayCastRT);
    float4 _SSRSettings2;
    #define BLUR_MULTIPLIER _SSRSettings2.y
    float4 _SSRSettings4;
    #define DENOISE_POWER _SSRSettings4.w
    float2 _SSRBlurStrength;
    #define BLUR_STRENGTH_HORIZ _SSRBlurStrength.x
    #define BLUR_STRENGTH_VERT _SSRBlurStrength.y

#if defined(UNITY_SINGLE_PASS_STEREO)
    #define SSR_VERTEX_CROSS_DATA
    #define SSR_VERTEX_OUTPUT_GAUSSIAN_UV(o)
    #if defined(SSR_BLUR_HORIZ)
        #define SSR_FRAG_SETUP_GAUSSIAN_UV(i) float2 offset1 = float2(_MainTex_TexelSize.x * 1.3846153846 * BLUR_STRENGTH_HORIZ, 0); float2 offset2 = float2(_MainTex_TexelSize.x * 3.2307692308 * BLUR_STRENGTH_HORIZ, 0);
    #else
        #define SSR_FRAG_SETUP_GAUSSIAN_UV(i) float2 offset1 = float2(0, _MainTex_TexelSize.y * 1.3846153846 * BLUR_STRENGTH_VERT); float2 offset2 = float2(0, _MainTex_TexelSize.y * 3.2307692308 * BLUR_STRENGTH_VERT);
    #endif

#else
    #define SSR_VERTEX_CROSS_DATA float2 offset1 : TEXCOORD1; float2 offset2 : TEXCOORD2;
    #if defined(SSR_BLUR_HORIZ)
        #define SSR_VERTEX_OUTPUT_GAUSSIAN_UV(o) o.offset1 = float2(_MainTex_TexelSize.x * 1.3846153846 * BLUR_STRENGTH_HORIZ, 0); o.offset2 = float2(_MainTex_TexelSize.x * 3.2307692308 * BLUR_STRENGTH_HORIZ, 0);
    #else
        #define SSR_VERTEX_OUTPUT_GAUSSIAN_UV(o) o.offset1 = float2(0, _MainTex_TexelSize.y * 1.3846153846 * BLUR_STRENGTH_VERT); o.offset2 = float2(0, _MainTex_TexelSize.y * 3.2307692308 * BLUR_STRENGTH_VERT);
    #endif
    #define SSR_FRAG_SETUP_GAUSSIAN_UV(i) float2 offset1 = i.offset1; float2 offset2 = i.offset2;

#endif

	struct AttributesFS {
		float4 positionHCS : POSITION;
		float2 uv          : TEXCOORD0;
		UNITY_VERTEX_INPUT_INSTANCE_ID
	};

 	struct VaryingsCross {
    	float4 positionCS : SV_POSITION;
    	float2 uv  : TEXCOORD0;
        SSR_VERTEX_CROSS_DATA
        UNITY_VERTEX_INPUT_INSTANCE_ID
        UNITY_VERTEX_OUTPUT_STEREO
	};


	VaryingsCross VertBlur(AttributesFS input) {
    	VaryingsCross output;
        UNITY_SETUP_INSTANCE_ID(v);
        UNITY_TRANSFER_INSTANCE_ID(input, output);
        UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);

        output.positionCS = float4(input.positionHCS.xyz, 1.0);

		#if UNITY_UV_STARTS_AT_TOP
		    output.positionCS.y *= -1;
		#endif

    	output.uv = input.uv;

        SSR_VERTEX_OUTPUT_GAUSSIAN_UV(output)

    	return output;
	}


	half4 FragBlur (VaryingsCross input): SV_Target {

        UNITY_SETUP_INSTANCE_ID(input);
        UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
        input.uv = SSRStereoTransformScreenSpaceTex(input.uv);
        SSR_FRAG_SETUP_GAUSSIAN_UV(input)

        float2 uv = input.uv;
        
	    half4 c0 = SAMPLE_TEXTURE2D_X(_MainTex, sampler_LinearClamp, uv);
        half4 c1 = SAMPLE_TEXTURE2D_X(_MainTex, sampler_LinearClamp, uv + offset1);
        half4 c2 = SAMPLE_TEXTURE2D_X(_MainTex, sampler_LinearClamp, uv - offset1);
        half4 c3 = SAMPLE_TEXTURE2D_X(_MainTex, sampler_LinearClamp, uv + offset2);
        half4 c4 = SAMPLE_TEXTURE2D_X(_MainTex, sampler_LinearClamp, uv - offset2);

        #if SSR_DENOISE
            half l0 = abs(getLuma(c0.rgb));
            half l1 = abs(getLuma(c1.rgb));
            half l2 = abs(getLuma(c2.rgb));
            half l3 = abs(getLuma(c3.rgb));
            half l4 = abs(getLuma(c4.rgb));

            half ml = (l0+l1+l2+l3+l4) * 0.2;
            c0.rgb *= pow( (1.0 + min(ml, l0)) / (1.0 + l0) , DENOISE_POWER);
            c1.rgb *= pow( (1.0 + min(ml, l1)) / (1.0 + l1) , DENOISE_POWER);
            c2.rgb *= pow( (1.0 + min(ml, l2)) / (1.0 + l2) , DENOISE_POWER);
            c3.rgb *= pow( (1.0 + min(ml, l3)) / (1.0 + l3) , DENOISE_POWER);
            c4.rgb *= pow( (1.0 + min(ml, l4)) / (1.0 + l4) , DENOISE_POWER);
        #endif

        half4 blurred = c0 * 0.2270270270 + (c1 + c2) * 0.3162162162 + (c3 + c4) * 0.0702702703;
   	    return blurred;
	}

#endif // SSR_BLUR