// SSAO 2
#version 450

layout(set = 0, binding = 0, std140) uniform freqHigh_fragmentUniforms_ubo
{
    vec4 renderpositiontoviewtexture;
    vec4 ssdoparms;
    vec4 ssdoparms2;
    vec4 texsize;
    vec4 framenumber;
} freqHigh_fragmentUniforms;

layout(set = 0, binding = 1, std140) uniform freqLow_fragmentUniforms_ubo
{
    vec4 projectionmatrixz;
    vec4 inverseviewmatrixx;
    vec4 inverseviewmatrixy;
    vec4 inverseviewmatrixz;
    vec4 resolutionscale;
    vec4 packedinverseprojection0;
    vec4 packedinverseprojection1;
    vec4 randomint;
    vec4 packedprojection;
} freqLow_fragmentUniforms;

layout(set = 0, binding = 2, std140) uniform sharedparmsuniformbuffer_ubo
{
    vec4 sharedparmsuniformbuffer[64];
} _791;

layout(set = 0, binding = 3) uniform sampler2D samp_viewdepthmap;
layout(set = 0, binding = 4) uniform sampler2D samp_tex0;
layout(set = 0, binding = 5) uniform sampler2D samp_tex3;
layout(set = 0, binding = 6) uniform sampler2D samp_tex2;
layout(set = 0, binding = 7) uniform sampler2D samp_tex1;

layout(location = 0) out vec4 out_FragColor0;

vec2 screenPosToTexcoord(vec2 pos, vec4 bias_scale)
{
    return (pos * bias_scale.zw) + bias_scale.xy;
}

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

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

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

vec2 OctWrap(vec2 v)
{
    float _296;
    if (v.x >= 0.0)
    {
        _296 = 1.0;
    }
    else
    {
        _296 = -1.0;
    }
    float _305;
    if (v.y >= 0.0)
    {
        _305 = 1.0;
    }
    else
    {
        _305 = -1.0;
    }
    return (vec2(1.0) - abs(v.yx)) * vec2(_296, _305);
}

vec3 NormalOctDecode(inout vec2 encN, bool expand_range)
{
    if (expand_range)
    {
        encN = (encN * 2.0) - vec2(1.0);
    }
    vec3 n;
    n.z = (1.0 - abs(encN.x)) - abs(encN.y);
    vec2 _335;
    if (n.z >= 0.0)
    {
        _335 = encN;
    }
    else
    {
        vec2 param = encN;
        _335 = OctWrap(param);
    }
    n = vec3(_335.x, _335.y, n.z);
    n = normalize(n);
    return n;
}

float sqr(float x)
{
    return x * x;
}

vec2 SmoothnessDecode(float s)
{
    float expanded_s = (s * 2.0) - 1.0;
    float param = expanded_s;
    float _361;
    if (expanded_s > 0.0)
    {
        _361 = 1.0;
    }
    else
    {
        _361 = 0.0;
    }
    return vec2(sqr(param), _361);
}

float GetNdcDepth(float linearZ, vec4 projectionMatrixZ)
{
    float ndcZ = (projectionMatrixZ.w / linearZ) - projectionMatrixZ.z;
    return ndcZ;
}

vec3 MatrixMul(mat3 m, vec3 v)
{
    return m * v;
}

mat3 BuildBasis(vec3 n)
{
    vec3 _251;
    if (n.x > 0.89999997615814208984375)
    {
        _251 = vec3(0.0, 1.0, 0.0);
    }
    else
    {
        _251 = vec3(1.0, 0.0, 0.0);
    }
    vec3 t = _251;
    t -= (n * dot(t, n));
    t = normalize(t);
    return mat3(vec3(t), vec3(cross(n, t)), vec3(n));
}

vec3 GetViewPos(vec3 winPos, vec4 inverseProjection0, vec4 inverseProjection1)
{
    return vec3((inverseProjection0.xy * winPos.xy) + inverseProjection0.zw, inverseProjection1.z) / vec3((inverseProjection1.x * winPos.z) + inverseProjection1.y);
}

uint ReverseBits4(inout uint idx)
{
    idx = ((idx & 1431655765u) << uint(1)) | ((idx & 2863311530u) >> uint(1));
    idx = ((idx & 858993459u) << uint(2)) | ((idx & 3435973836u) >> uint(2));
    return idx;
}

vec2 Hammersley2D_4bits(uint numSamples, uint idx)
{
    float rcpNumSamples = 1.0 / float(numSamples);
    uint param = idx + 1u;
    uint _243 = ReverseBits4(param);
    return vec2(float(idx + 1u) * rcpNumSamples, float(_243) / 16.0);
}

vec2 GetWindowPos(vec3 viewPos, vec4 projection)
{
    return vec2(0.5) + (projection.xy * (viewPos.xy / vec2(viewPos.z)));
}

void main()
{
    vec2 param = gl_FragCoord.xy;
    vec4 param_1 = freqHigh_fragmentUniforms.renderpositiontoviewtexture;
    vec2 tc = screenPosToTexcoord(param, param_1);
        
    bool _387;
    if (freqHigh_fragmentUniforms.ssdoparms.x == 1.0)
    {
        _387 = true;
    }
    else
    {
        _387 = false;
    }
    bool taaEnabled = _387;
    int numRays = 12;
    int numRaysOuter = 8;
    float accNormalization = 1.0 / float(numRays - numRaysOuter);
    float accOuterNormalization = 1.0 / float(numRaysOuter);
    float angle_bias = freqHigh_fragmentUniforms.ssdoparms2.z;
    float position_bias = freqHigh_fragmentUniforms.ssdoparms2.w;
    out_FragColor0 = vec4(1.0);
    vec4 param_2 = vec4(tc, 0.0, 0.0);
    float ndcZ = tex2Dlod(samp_viewdepthmap, param_2).x;
    float param_3 = ndcZ;
    vec4 param_4 = freqLow_fragmentUniforms.projectionmatrixz;
    float param_5 = 1.0;
    bool param_6 = false;
    float linearZ = GetLinearDepth(param_3, param_4, param_5, param_6);
    float param_7 = (freqHigh_fragmentUniforms.ssdoparms.y - linearZ) / 256.0;
    float distAtten = saturate(param_7);
    vec4 param_8 = vec4(tc, 0.0, 0.0);
    vec2 param_9 = tex2Dlod(samp_tex0, param_8).xy;
    bool param_10 = false;
    vec3 _463 = NormalOctDecode(param_9, param_10);
    vec4 param_11 = vec4(tc, 0.0, 0.0);
    float param_12 = tex2Dlod(samp_tex3, param_11).w;
    vec4 n1 = vec4(_463, SmoothnessDecode(param_12).y);
    /*
    if ((distAtten * n1.w) > 0.0)
    {
        float param_13 = 3.5;
        vec4 param_14 = freqLow_fragmentUniforms.projectionmatrixz;
        float firstPersonArmsZ = GetNdcDepth(param_13, param_14);
        float _494;
        if (ndcZ < firstPersonArmsZ)
        {
            _494 = freqHigh_fragmentUniforms.ssdoparms2.w;
        }
        else
        {
            _494 = freqHigh_fragmentUniforms.ssdoparms2.y;
        }
        float radii = _494;
        float _507;
        if (ndcZ < firstPersonArmsZ)
        {
            _507 = freqHigh_fragmentUniforms.ssdoparms2.z;
        }
        else
        {
            _507 = freqHigh_fragmentUniforms.ssdoparms2.x;
        }
        float radii_inner = _507;
        float max_radius_ws = 1.0 / radii;
        float _523;
        if (ndcZ < firstPersonArmsZ)
        {
            _523 = freqHigh_fragmentUniforms.ssdoparms.w * 0.5;
        }
        else
        {
            _523 = freqHigh_fragmentUniforms.ssdoparms.w;
        }
        float normalBias = _523;
        float _536;
        if (ndcZ < firstPersonArmsZ)
        {
            _536 = ndcZ * 10.0;
        }
        else
        {
            _536 = ndcZ;
        }
        ndcZ = _536;
        vec4 param_15 = vec4(tc + ((freqHigh_fragmentUniforms.texsize.zw * 0.5) * vec2(1.0, 0.0)), 0.0, 0.0);
        vec2 param_16 = tex2Dlod(samp_tex0, param_15).xy;
        bool param_17 = false;
        vec3 _565 = NormalOctDecode(param_16, param_17);
        vec3 n2 = _565;
        vec4 param_18 = vec4(tc + ((freqHigh_fragmentUniforms.texsize.zw * 0.5) * vec2(0.0, 1.0)), 0.0, 0.0);
        vec2 param_19 = tex2Dlod(samp_tex0, param_18).xy;
        bool param_20 = false;
        vec3 _583 = NormalOctDecode(param_19, param_20);
        vec3 n3 = _583;
        vec4 param_21 = vec4(tc + ((freqHigh_fragmentUniforms.texsize.zw * 0.5) * vec2(1.0)), 0.0, 0.0);
        vec2 param_22 = tex2Dlod(samp_tex0, param_21).xy;
        bool param_23 = false;
        vec3 _601 = NormalOctDecode(param_22, param_23);
        vec3 n4 = _601;
        vec3 gbufN = (((n1.xyz + n2) + n3) + n4) / vec3(4.0);
        vec3 normalM = gbufN;
        mat3 invProjT = mat3(vec3(freqLow_fragmentUniforms.inverseviewmatrixx.xyz), vec3(freqLow_fragmentUniforms.inverseviewmatrixy.xyz), vec3(freqLow_fragmentUniforms.inverseviewmatrixz.xyz));
        mat3 param_24 = invProjT;
        vec3 param_25 = normalM;
        vec3 normalVS = normalize(MatrixMul(param_24, param_25));
        vec3 param_26 = normalVS;
        mat3 basisN = BuildBasis(param_26);
        ndcZ -= freqHigh_fragmentUniforms.ssdoparms.z;
        vec3 param_27 = vec3(tc / freqLow_fragmentUniforms.resolutionscale.xy, ndcZ);
        vec4 param_28 = freqLow_fragmentUniforms.packedinverseprojection0;
        vec4 param_29 = freqLow_fragmentUniforms.packedinverseprojection1;
        vec3 viewPosOrig = GetViewPos(param_27, param_28, param_29);
        viewPosOrig += (normalVS * normalBias);
        ivec2 pix_idx = ivec2(ivec2(gl_FragCoord.xy) + (ivec2(0) * ivec2(freqLow_fragmentUniforms.randomint.xy))) & ivec2(1);
        int idx_pix = pix_idx.x + (pix_idx.y * 2);
        float _709;
        if (taaEnabled)
        {
            _709 = freqHigh_fragmentUniforms.framenumber.x;
        }
        else
        {
            _709 = 0.0;
        }
        uint param_30 = 4u;
        uint param_31 = uint((idx_pix + int(_709)) & 3);
        vec3 noiseVec = vec3((Hammersley2D_4bits(param_30, param_31) * 2.0) - vec2(1.0), 0.0);
        mat3 param_32 = basisN;
        vec3 param_33 = noiseVec;
        noiseVec = normalize(MatrixMul(param_32, param_33));
        vec3 T = normalize(noiseVec - (normalVS * dot(noiseVec, normalVS)));
        vec3 B = cross(normalVS, T);
        mat3 TBN = mat3(vec3(T), vec3(B), vec3(normalVS));
        float unoccl_ratio = 0.0;
        float _776;
        vec3 winPosTap;
        int _866;
        int _880;
        for (int t = 0; t < numRays; t++)
        {
            if (t >= numRaysOuter)
            {
                _776 = radii_inner;
            }
            else
            {
                _776 = radii;
            }
            radii = _776;
            mat3 param_34 = TBN;
            vec3 param_35 = _791.sharedparmsuniformbuffer[t].xyz;
            vec3 ray_dir = vec3(MatrixMul(param_34, param_35));
            vec3 viewPosHemisphere = viewPosOrig + (ray_dir * radii);
            vec3 param_36 = viewPosHemisphere;
            vec4 param_37 = freqLow_fragmentUniforms.packedprojection;
            vec2 _816 = GetWindowPos(param_36, param_37);
            winPosTap = vec3(_816.x, _816.y, winPosTap.z);
            if (t < numRaysOuter)
            {
                vec4 param_38 = vec4(winPosTap.xy * freqLow_fragmentUniforms.resolutionscale.xy, 0.0, 0.0);
                winPosTap.z = 1.0 - tex2Dlod(samp_tex2, param_38).x;
            }
            else
            {
                vec4 param_39 = vec4(winPosTap.xy * freqLow_fragmentUniforms.resolutionscale.xy, 0.0, 0.0);
                winPosTap.z = 1.0 - tex2Dlod(samp_tex1, param_39).x;
            }
            vec3 param_40 = winPosTap;
            vec4 param_41 = freqLow_fragmentUniforms.packedinverseprojection0;
            vec4 param_42 = freqLow_fragmentUniforms.packedinverseprojection1;
            vec3 viewPosTap = GetViewPos(param_40, param_41, param_42);
            if (abs(viewPosOrig.z - viewPosTap.z) < radii)
            {
                _866 = 1;
            }
            else
            {
                _866 = 0;
            }
            float tap_discard = float(_866);
            if (viewPosTap.z > viewPosHemisphere.z)
            {
                _880 = 1;
            }
            else
            {
                _880 = 0;
            }
            unoccl_ratio += (float(_880) * tap_discard);
        }
        unoccl_ratio /= 12.0;
        float param_43 = 1.0 - (unoccl_ratio * distAtten);
        out_FragColor0.x = saturate(param_43);
    }
*/
}


