﻿Shader "SnapshotProHDRP/LightStreaks"
{
    HLSLINCLUDE

    #pragma target 4.5
    #pragma only_renderers d3d11 ps4 xboxone vulkan metal switch

    #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
    #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"
    #include "Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl"
    #include "Packages/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/Shaders/FXAA.hlsl"
    #include "Packages/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/Shaders/RTUpscale.hlsl"

    struct Attributes
    {
        uint vertexID : SV_VertexID;
        UNITY_VERTEX_INPUT_INSTANCE_ID
    };

    struct Varyings
    {
        float4 positionCS : SV_POSITION;
        float2 texcoord   : TEXCOORD0;
        UNITY_VERTEX_OUTPUT_STEREO
    };

    Varyings Vert(Attributes input)
    {
        Varyings output;
        UNITY_SETUP_INSTANCE_ID(input);
        UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
        output.positionCS = GetFullScreenTriangleVertexPosition(input.vertexID);
        output.texcoord = GetFullScreenTriangleTexCoord(input.vertexID);
        return output;
    }

    // List of properties to control your post process effect
	TEXTURE2D_X(_InputTexture);
	TEXTURE2D(_OverlayTexture);
	uint _KernelSize;
	float _Spread;

	float _LuminanceThreshold;

	static const float E = 2.71828f;

	float gaussian(int x)
	{
		float sigmaSqu = _Spread * _Spread;
		return (1 / sqrt(TWO_PI * sigmaSqu)) * pow(E, -(x * x) / (2 * sigmaSqu));
	}

    float4 CustomPostProcess_Blur(Varyings input) : SV_Target
    {
        UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);

        uint2 positionSS = input.texcoord * _ScreenSize.xy;

		float3 col = LOAD_TEXTURE2D_X(_InputTexture, positionSS).xyz;
		float3 light = 0.0f;
		float kernelSum = 0.0f;

		int upper = ((_KernelSize - 1) / 2);
		int lower = -upper;

		float2 uv;

		for (int x = lower; x <= upper; ++x)
		{
			float gauss = gaussian(x);
			kernelSum += gauss;
			uv = positionSS + int2(x, 0);

			float3 newLight = LOAD_TEXTURE2D_X(_InputTexture, uv).rgb;
			float lum = Luminance(newLight);
			light += step(_LuminanceThreshold, lum) * newLight * gauss;
		}

		light /= kernelSum;

		return float4(light, 1.0f);
    }

	float4 CustomPostProcess_Overlay(Varyings input) : SV_Target
    {
        UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);

        uint2 positionSS = input.texcoord * _ScreenSize.xy;

		float4 mainCol = LOAD_TEXTURE2D_X(_InputTexture, positionSS);
		float4 blurCol = SAMPLE_TEXTURE2D(_OverlayTexture, s_linear_clamp_sampler, input.texcoord);

		return mainCol + blurCol;
    }

    ENDHLSL

    SubShader
    {
        Pass
        {
            Name "Blur"

            ZWrite Off
            ZTest Always
            Blend Off
            Cull Off

            HLSLPROGRAM
                #pragma fragment CustomPostProcess_Blur
                #pragma vertex Vert
            ENDHLSL
        }

		Pass
        {
            Name "Overlay"

            ZWrite Off
            ZTest Always
            Blend Off
            Cull Off

            HLSLPROGRAM
                #pragma fragment CustomPostProcess_Overlay
                #pragma vertex Vert
            ENDHLSL
        }
    }
    Fallback Off
}
