// All the SHINNY
#version 450

// Vk3DVision (http://3dsurroundgaming.com/) - Stereo Injection
layout(set = 0, binding = 30, std140) uniform Vk3DParams
{
    vec4 stereo;
    vec4 custom_params;
} vk3d_params;

layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;

layout(set = 0, binding = 0, std140) uniform freqHigh_computeUniforms_ubo
{
    vec4 renderpositiontoviewtexture;
    vec4 ssdoparms;
    vec4 ssdoparms2;
} freqHigh_computeUniforms;

layout(set = 0, binding = 1, std140) uniform freqLow_computeUniforms_ubo
{
    vec4 resolutionscale;
    vec4 windowpostoglobalx;
    vec4 windowpostoglobaly;
    vec4 windowpostoglobalz;
    vec4 windowpostoglobalw;
    vec4 fogparms2;
    vec4 globalvieworigin;
    vec4 fogparms1;
    vec4 foglightinscatterdirection;
    vec4 foglightinscattercolor;
    vec4 foglightinscatterintensity;
    vec4 foglightoppositecolor;
    vec4 projectionmatrixz;
    vec4 fogparms;
    vec4 fogcolor;
    vec4 transparencylightmult;
} freqLow_computeUniforms;

layout(set = 0, binding = 2) uniform sampler2D samp_viewdepthmap;
layout(set = 0, binding = 3) uniform sampler2D samp_tex4;
layout(set = 0, binding = 4) uniform sampler2D samp_tex0;
layout(set = 0, binding = 5) uniform sampler2D samp_tex2;
layout(set = 0, binding = 6) uniform sampler2D samp_tex3;
layout(set = 0, binding = 7) uniform sampler2D samp_tex1;
layout(set = 0, binding = 8, r11f_g11f_b10f) uniform image2D ib_uavdeferredcomposite0;
layout(set = 0, binding = 9, r11f_g11f_b10f) uniform writeonly image2D ib_uavdeferredcomposite1;

vec4 tex2Dlod(sampler2D image, vec4 texcoord)
{
    return textureLod(image, texcoord.xy, texcoord.w);
}

vec2 saturate(vec2 v)
{
    return clamp(v, vec2(0.0), vec2(1.0));
}

float dot4(vec4 a, vec4 b)
{
    return dot(a, b);
}

float saturate(float v)
{
    return clamp(v, 0.0, 1.0);
}

float GetLinearDepth(float ndcZ, vec4 projectionMatrixZ, float rcpFarZ, bool bFirstPersonArmsRescale)
{
    float linearZ = projectionMatrixZ.w / (ndcZ + projectionMatrixZ.z);
    if (bFirstPersonArmsRescale)
    {
        float _81;
        if (linearZ < 1.0)
        {
            _81 = 10.0;
        }
        else
        {
            _81 = 1.0;
        }
        linearZ *= _81;
    }
    return linearZ * rcpFarZ;
}

void main()
{
    ivec3 pixelLocation = ivec3(gl_GlobalInvocationID);
    vec2 tc = (vec2(pixelLocation.xy) + vec2(0.5)) * freqHigh_computeUniforms.renderpositiontoviewtexture.zw;
//	tc.x -= vk3d_params.stereo.x * 0.5;
    
    vec4 param = vec4(tc, 0.0, 0.0);
    float ndcZ = tex2Dlod(samp_viewdepthmap, param).x;
    vec4 outputColor = vec4(0.0, 0.0, 0.0, 1.0);
    bool clearMask = false;
    if (ndcZ < 1.0)
    {
        vec2 directional_occlusion = vec2(1.0);
        if (freqHigh_computeUniforms.ssdoparms.y > 0.0)
        {
            vec4 param_1 = vec4(tc, 0.0, 0.0);
            vec2 param_2 = pow(tex2Dlod(samp_tex4, param_1).xx, freqHigh_computeUniforms.ssdoparms.zw);
            directional_occlusion = saturate(param_2);
        }
        vec4 param_3 = vec4(tc, 0.0, 0.0);
        vec3 specularBuffer = tex2Dlod(samp_tex0, param_3).xyz;
        if (freqHigh_computeUniforms.ssdoparms2.x > 0.0)
        {
            vec4 param_4 = vec4(tc + (freqHigh_computeUniforms.renderpositiontoviewtexture.zw * 0.25), 0.0, 0.0);
            vec3 ssrBuffer = tex2Dlod(samp_tex2, param_4).xyz;
            vec4 param_5 = vec4(tc, 0.0, 0.0);
            float ssrMask = tex2Dlod(samp_tex3, param_5).x;
            specularBuffer = mix(specularBuffer, ssrBuffer, vec3(ssrMask));
        }
        outputColor = vec4(specularBuffer * directional_occlusion.y, directional_occlusion.x);
    }
    else
    {
        vec4 param_6 = vec4(tc, 0.0, 0.0);
        bool _221;
        if (dot(tex2Dlod(samp_tex1, param_6), vec4(1.0)) == 0.0)
        {
            _221 = false;
        }
        else
        {
            _221 = true;
        }
        clearMask = _221;
    }
    vec3 dstColor = imageLoad(ib_uavdeferredcomposite0, pixelLocation.xy).xyz;
    vec3 _246;
    if ((ndcZ == 1.0) && clearMask)
    {
        _246 = vec3(0.0);
    }
    else
    {
        _246 = outputColor.xyz + (dstColor * outputColor.w);
    }
    dstColor = _246;
    if (freqHigh_computeUniforms.ssdoparms2.w == 1.0)
    {
        tc /= freqLow_computeUniforms.resolutionscale.xy;
        vec4 windowPosition;
        windowPosition = vec4(tc.x, tc.y, windowPosition.z, windowPosition.w);
        windowPosition.z = ndcZ;
        windowPosition.w = 1.0;
        vec4 param_7 = windowPosition;
        vec4 param_8 = freqLow_computeUniforms.windowpostoglobalx;
        vec4 globalPosition;
        globalPosition.x = dot4(param_7, param_8);
        vec4 param_9 = windowPosition;
        vec4 param_10 = freqLow_computeUniforms.windowpostoglobaly;
        globalPosition.y = dot4(param_9, param_10);
        vec4 param_11 = windowPosition;
        vec4 param_12 = freqLow_computeUniforms.windowpostoglobalz;
        globalPosition.z = dot4(param_11, param_12);
        vec4 param_13 = windowPosition;
        vec4 param_14 = freqLow_computeUniforms.windowpostoglobalw;
        globalPosition.w = dot4(param_13, param_14);
        vec3 _319 = globalPosition.xyz / vec3(globalPosition.w);
        globalPosition = vec4(_319.x, _319.y, _319.z, globalPosition.w);
        float FLT_EPSILON = 9.9999997473787516355514526367188e-05;
        float heightFogAmount = 0.0;
        vec3 heightFogColor = vec3(0.0);
        if (freqLow_computeUniforms.fogparms2.z < 1.0)
        {
            vec3 cameraToPixel = globalPosition.xyz - freqLow_computeUniforms.globalvieworigin.xyz;
            float distanceToPixel = length(cameraToPixel);
            float be = freqLow_computeUniforms.fogparms2.x * exp2((-freqLow_computeUniforms.fogparms1.w) * (freqLow_computeUniforms.globalvieworigin.z - freqLow_computeUniforms.fogparms1.x));
            float distanceInFog = max(distanceToPixel - freqLow_computeUniforms.fogparms2.y, 0.0);
            float effectiveZ = max(cameraToPixel.z, FLT_EPSILON);
            if (cameraToPixel.z < (-FLT_EPSILON))
            {
                effectiveZ = cameraToPixel.z;
            }
            float lineIntegral = be * distanceInFog;
            lineIntegral *= ((1.0 - exp2((-freqLow_computeUniforms.fogparms1.w) * effectiveZ)) / (freqLow_computeUniforms.fogparms1.w * effectiveZ));
            float cosL = dot(freqLow_computeUniforms.foglightinscatterdirection.xyz, normalize(cameraToPixel));
            float param_15 = (cosL - freqLow_computeUniforms.fogparms1.y) * freqLow_computeUniforms.fogparms1.z;
            float blendValue = saturate(param_15);
            float inscatterAlpha = 1.0 - (blendValue * blendValue);
            vec3 fogLightInscatterScaledColor = freqLow_computeUniforms.foglightinscattercolor.xyz * freqLow_computeUniforms.foglightinscatterintensity.x;
            heightFogColor = mix(fogLightInscatterScaledColor, freqLow_computeUniforms.foglightoppositecolor.xyz, vec3(inscatterAlpha));
            float param_16 = exp2(-lineIntegral);
            heightFogAmount = 1.0 - max(saturate(param_16), freqLow_computeUniforms.fogparms2.z);
        }
        float param_17 = ndcZ;
        vec4 param_18 = freqLow_computeUniforms.projectionmatrixz;
        float param_19 = 1.0;
        bool param_20 = false;
        float viewZ = GetLinearDepth(param_17, param_18, param_19, param_20);
        float fogDepth = clamp(viewZ - freqLow_computeUniforms.fogparms.x, 0.0, freqLow_computeUniforms.fogparms.y) * freqLow_computeUniforms.fogparms.z;
        float param_21 = exp2(-fogDepth);
        float distanceFog = 1.0 - saturate(param_21);
        float param_22 = heightFogAmount + distanceFog;
        float fogDensity = saturate(param_22);
        float fogSafeAmount = max(fogDensity, FLT_EPSILON);
        float fogSelection = max(0.0, (fogSafeAmount - distanceFog) / fogSafeAmount);
        vec3 fogColor = mix(freqLow_computeUniforms.fogcolor.xyz, heightFogColor, vec3(fogSelection));
        float param_23 = fogDensity * freqLow_computeUniforms.fogparms2.w;
        dstColor = mix(dstColor, fogColor * freqLow_computeUniforms.transparencylightmult.x, vec3(saturate(param_23)));
    }
    imageStore(ib_uavdeferredcomposite0, pixelLocation.xy, vec4(dstColor, 1.0));
    imageStore(ib_uavdeferredcomposite1, pixelLocation.xy, vec4(dstColor, 1.0));
}


