// No idea
#version 460
#extension GL_EXT_nonuniform_qualifier : require

struct particleubermaterial_t
{
    vec4 particleUberParms1;
    vec4 particleUberParms2;
    vec4 particleUberParms3;
    uvec4 tilingPacked;
    vec4 particleFade_emissive_pad;
    uvec4 scaleBias01;
    uvec4 scaleBias23;
};

struct clusternumlights_t
{
    int offset;
    int numItems;
};

layout(set = 2, binding = 0, std140) uniform _surfaceUniforms_ubo
{
    vec4 particleuberparms1;
    vec4 particleuberparms2;
    vec4 particleuberparms3;
    vec4 tiling;
    vec4 tiling2;
    vec4 particlefade;
    vec4 emissive;
    vec4 transmapscalebias;
    vec4 transmapscalebias1;
    vec4 transmapscalebias2;
    vec4 transmapidx;
} _surfaceUniforms;

layout(set = 0, binding = 0, std140) uniform _viewUniforms_ubo
{
    vec4 viewprojectionmatrixx;
    vec4 viewprojectionmatrixy;
    vec4 viewprojectionmatrixz;
    vec4 viewprojectionmatrixw;
    vec4 fragmentpositiontoviewtexture;
    vec4 projectionmatrixz;
    vec4 clusteredlighting;
    vec4 particleatlasparms;
    vec4 usebindlesstextures;
    vec4 particlemult;
    vec4 fogparms;
    vec4 lightscatteringres;
    vec4 lightscatteringparms;
    vec4 globalvieworigin;
    vec4 frustumvectl;
    vec4 frustumvectr;
    vec4 resolutionscale;
    vec4 frustumvecbl;
    vec4 frustumvecbr;
    vec4 znearfar;
    vec4 watervolumeviewparms;
} _viewUniforms;

layout(set = 1, binding = 0, std140) uniform _instanceUniforms_ubo
{
    vec4 modelmatrixx;
    vec4 modelmatrixy;
    vec4 modelmatrixz;
    vec4 modelmatrixw;
    vec4 particlestscalebias;
    vec4 particlecolorscale;
    vec4 particlecolorbias;
} _instanceUniforms;

layout(set = 0, binding = 1, std430) restrict readonly buffer clusternumlights_b
{
    clusternumlights_t clusternumlights[];
} _1272;

layout(set = 0, binding = 2, std430) restrict readonly buffer clusterlightsid_b
{
    uint clusterlightsid[];
} _1276;

layout(set = 0, binding = 3, std140) uniform lightparms1_ubo
{
    vec4 lightparms1[4096];
} _1281;

layout(set = 0, binding = 4, std140) uniform lightparms2_ubo
{
    vec4 lightparms2[4096];
} _1285;

layout(set = 0, binding = 5, std140) uniform lightparms3_ubo
{
    vec4 lightparms3[4096];
} _1289;

layout(push_constant, std430) uniform PushConstants
{
    int lodLevel;
    int modelIndex;
} pushConstants;

layout(set = 0, binding = 7) uniform sampler2D samp_particleslightatlasmap;
layout(set = 3, binding = 0) uniform texture2D globalTextures[65536];
layout(set = 0, binding = 8) uniform sampler samp_loosealbedosampler;
layout(set = 2, binding = 1) uniform sampler2D samp_transmap;
layout(set = 0, binding = 9) uniform sampler2D samp_viewdepthmap;
layout(set = 0, binding = 10) uniform sampler3D samp_finallightscatteringpacked0map;
layout(set = 0, binding = 11) uniform sampler3D samp_finallightscatteringpacked1map;
layout(set = 0, binding = 12) uniform sampler3D samp_skylightinglutmap;
layout(set = 0, binding = 13) uniform sampler2D samp_watergbufferdepthmap;
layout(set = 0, binding = 6) uniform samplerCubeArray samp_envprobesmaparray;

layout(location = 3) in vec4 vofi_TexCoord1;
layout(location = 6) in vec4 vofi_TexCoord4;
layout(location = 2) in vec4 vofi_TexCoord0;
layout(location = 0) in vec4 vofi_Color;
layout(location = 0) out vec4 out_FragColor0;
layout(location = 1) out vec4 out_FragColor1;
layout(location = 2) out vec4 out_FragColor2;

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

float w0(float a)
{
    return 0.16666667163372039794921875 * ((a * ((a * ((-a) + 3.0)) - 3.0)) + 1.0);
}

float w1(float a)
{
    return 0.16666667163372039794921875 * (((a * a) * ((3.0 * a) - 6.0)) + 4.0);
}

float g0(float a)
{
    float param = a;
    float param_1 = a;
    return w0(param) + w1(param_1);
}

float w2(float a)
{
    return 0.16666667163372039794921875 * ((a * ((a * (((-3.0) * a) + 3.0)) + 3.0)) + 1.0);
}

float w3(float a)
{
    return 0.16666667163372039794921875 * ((a * a) * a);
}

float g1(float a)
{
    float param = a;
    float param_1 = a;
    return w2(param) + w3(param_1);
}

float h0(float a)
{
    float param = a;
    float param_1 = a;
    float param_2 = a;
    return (-1.0) + (w1(param) / (w0(param_1) + w1(param_2)));
}

float h1(float a)
{
    float param = a;
    float param_1 = a;
    float param_2 = a;
    return 1.0 + (w3(param) / (w2(param_1) + w3(param_2)));
}

vec4 tex2DBicubic(sampler2D image, inout vec2 uv, vec2 res)
{
    uv = (uv * res) + vec2(0.5);
    vec2 iuv = floor(uv);
    vec2 fuv = fract(uv);
    float param = fuv.x;
    float g0x = g0(param);
    float param_1 = fuv.x;
    float g1x = g1(param_1);
    float param_2 = fuv.x;
    float h0x = h0(param_2);
    float param_3 = fuv.x;
    float h1x = h1(param_3);
    float param_4 = fuv.y;
    float h0y = h0(param_4);
    float param_5 = fuv.y;
    float h1y = h1(param_5);
    vec2 p0 = (vec2(iuv.x + h0x, iuv.y + h0y) - vec2(0.5)) / res;
    vec2 p1 = (vec2(iuv.x + h1x, iuv.y + h0y) - vec2(0.5)) / res;
    vec2 p2 = (vec2(iuv.x + h0x, iuv.y + h1y) - vec2(0.5)) / res;
    vec2 p3 = (vec2(iuv.x + h1x, iuv.y + h1y) - vec2(0.5)) / res;
    vec4 t0 = textureLod(image, vec4(p0, 0.0, 0.0).xy, vec4(p0, 0.0, 0.0).w);
    vec4 t1 = textureLod(image, vec4(p1, 0.0, 0.0).xy, vec4(p1, 0.0, 0.0).w);
    vec4 t2 = textureLod(image, vec4(p2, 0.0, 0.0).xy, vec4(p2, 0.0, 0.0).w);
    vec4 t3 = textureLod(image, vec4(p3, 0.0, 0.0).xy, vec4(p3, 0.0, 0.0).w);
    float param_6 = fuv.y;
    float param_7 = fuv.y;
    return (((t0 * g0x) + (t1 * g1x)) * g0(param_6)) + (((t2 * g0x) + (t3 * g1x)) * g1(param_7));
}

uint asuint(float x)
{
    return floatBitsToUint(x);
}

float SRGBlinearApprox(float value)
{
    return value * ((value * ((value * 0.305306017398834228515625) + 0.6821711063385009765625)) + 0.01252287812530994415283203125);
}

vec3 SRGBlinearApprox(vec3 sRGB)
{
    float param = sRGB.x;
    vec3 outLinear;
    outLinear.x = SRGBlinearApprox(param);
    float param_1 = sRGB.y;
    outLinear.y = SRGBlinearApprox(param_1);
    float param_2 = sRGB.z;
    outLinear.z = SRGBlinearApprox(param_2);
    return outLinear;
}

vec4 SRGBlinearApprox(vec4 sRGBA)
{
    vec3 param = sRGBA.xyz;
    vec4 outLinear = vec4(SRGBlinearApprox(param), 1.0);
    float param_1 = sRGBA.w;
    outLinear.w = SRGBlinearApprox(param_1);
    return outLinear;
}

vec4 tex2DDeGammaApprox(sampler2D image, vec2 texcoord)
{
    vec4 color = texture(image, texcoord);
    vec4 param = color;
    color = SRGBlinearApprox(param);
    return color;
}

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

void clip(float v)
{
    if (v < 0.0)
    {
        discard;
    }
}

float GetLinearDepth(float ndcZ, vec4 projectionMatrixZ, float rcpFarZ, bool bFirstPersonArmsRescale)
{
    float linearZ = projectionMatrixZ.w / (ndcZ + projectionMatrixZ.z);
    return linearZ * rcpFarZ;
}

float fastAcos(float x)
{
    float res = (((-0.15658299624919891357421875) * abs(x)) + 1.57079637050628662109375) * sqrt(1.0 - abs(x));
    float _190;
    if (x >= 0.0)
    {
        _190 = res;
    }
    else
    {
        _190 = 3.1415927410125732421875 - res;
    }
    return _190;
}

float fastAtanPos(float x)
{
    float _204;
    if (x < 1.0)
    {
        _204 = x;
    }
    else
    {
        _204 = 1.0 / x;
    }
    float t0 = _204;
    float t1 = t0 * t0;
    float poly = 0.087292902171611785888671875;
    poly = (-0.3018949925899505615234375) + (poly * t1);
    poly = 1.0 + (poly * t1);
    poly *= t0;
    float _232;
    if (x < 1.0)
    {
        _232 = poly;
    }
    else
    {
        _232 = 1.57079637050628662109375 - poly;
    }
    return _232;
}

float fastAtan(float x)
{
    float param = abs(x);
    float t0 = fastAtanPos(param);
    float _249;
    if (x < 0.0)
    {
        _249 = -t0;
    }
    else
    {
        _249 = t0;
    }
    return _249;
}

float fastAtan2(float y, float x)
{
    float param = y / x;
    float angle = fastAtan(param);
    if (x < 0.0)
    {
        angle += ((y >= 0.0) ? 3.1415927410125732421875 : (-3.1415927410125732421875));
    }
    return angle;
}

void main()
{
    particleubermaterial_t mtl;
    mtl.particleUberParms1 = _surfaceUniforms.particleuberparms1;
    mtl.particleUberParms2 = _surfaceUniforms.particleuberparms2;
    mtl.particleUberParms3 = _surfaceUniforms.particleuberparms3;
    mtl.particleFade_emissive_pad = vec4(_surfaceUniforms.particlefade.xy, _surfaceUniforms.emissive.x, 0.0);
    vec4 scaleBias0 = _surfaceUniforms.transmapscalebias;
    vec4 scaleBias1 = _surfaceUniforms.transmapscalebias1;
    vec4 scaleBias2 = _surfaceUniforms.transmapscalebias2;
    float modeUnlitParticle = 0.0;
    float modeLitParticle = 1.0;
    float modeSmokeParticle = 2.0;
    float modeLitSmokeParticle = 3.0;
    float modeFluidParticle = 4.0;
    float modeLitFluidParticle = 5.0;
    float modeExperimentation = 32.0;
    float uberMode = mtl.particleUberParms1.x;
    float fluidDissolve = mtl.particleUberParms1.y;
    float gunParticle = 0.0;
    float constantSpec = mtl.particleUberParms1.w;
    vec3 color2 = mtl.particleUberParms2.xyz;
    float constantSmoothness = mtl.particleUberParms2.w;
    vec3 color3 = mtl.particleUberParms3.xyz;
    float rp_emissiveMult = mtl.particleUberParms3.w;
    float interpolatedZOverW = gl_FragCoord.z;
    float vp_emissiveMult = vofi_TexCoord1.x;
    float depthAlphaMul_Raw = vofi_TexCoord1.y;
    float frameFrac = vofi_TexCoord1.z;
    float alphaFade = vofi_TexCoord1.w;
    float alphaMul = vofi_TexCoord4.z;
    float param = depthAlphaMul_Raw;
    float param_1 = (depthAlphaMul_Raw * 2.0) - 1.0;
    float depthAlphaMul = mix(saturate(param), 9.0, saturate(param_1));
    vec2 tc = gl_FragCoord.xy * _viewUniforms.fragmentpositiontoviewtexture.zw;
    vec3 diffuse_lighting = vec3(1.0);
    if (((uberMode == modeLitParticle) || (uberMode == modeLitSmokeParticle)) || (uberMode == modeLitFluidParticle))
    {
        vec2 param_2 = vofi_TexCoord4.xy;
        vec2 param_3 = _viewUniforms.particleatlasparms.xy;
        vec4 _720 = tex2DBicubic(samp_particleslightatlasmap, param_2, param_3);
        diffuse_lighting = _720.xyz;
    }
    vec4 final = vec4(5.0, 0.0, 5.0, 1.0);
    if ((uberMode == modeLitParticle) || (uberMode == modeUnlitParticle))
    {
        vec2 uv0 = (vofi_TexCoord0.xy * scaleBias0.xy) + scaleBias0.zw;
        vec2 uv1 = (vofi_TexCoord0.zw * scaleBias0.xy) + scaleBias0.zw;
        vec4 result0;
        vec4 result1;
        if (_viewUniforms.usebindlesstextures.x == 1.0)
        {
            float param_4 = _surfaceUniforms.transmapidx.x;
            uint albedoIdx = asuint(param_4);
            uint _770 = albedoIdx;
            vec4 param_5 = texture(sampler2D(globalTextures[nonuniformEXT(_770)], samp_loosealbedosampler), uv0);
            result0 = SRGBlinearApprox(param_5) * (1.0 - frameFrac);
            uint _788 = albedoIdx;
            vec4 param_6 = texture(sampler2D(globalTextures[nonuniformEXT(_788)], samp_loosealbedosampler), uv1);
            result1 = SRGBlinearApprox(param_6) * frameFrac;
        }
        else
        {
            vec2 param_7 = uv0;
            result0 = tex2DDeGammaApprox(samp_transmap, param_7) * (1.0 - frameFrac);
            vec2 param_8 = uv1;
            result1 = tex2DDeGammaApprox(samp_transmap, param_8) * frameFrac;
        }
        final = result0 + result1;
        vec4 param_9 = (final * _instanceUniforms.particlecolorscale) + _instanceUniforms.particlecolorbias;
        final = saturate(param_9);
        float param_10 = final.w - 9.9999999747524270787835121154785e-07;
        clip(param_10);
        float opacitySoftZScale = 1.0;
        float depth = textureLod(samp_viewdepthmap, vec4(tc, 0.0, 0.0).xy, vec4(tc, 0.0, 0.0).w).x;
        float r1 = 1.0 / (1.0 - depth);
        float r2 = 1.0 / (1.0 - gl_FragCoord.z);
        float param_11 = (r1 - r2) * depthAlphaMul;
        opacitySoftZScale = saturate(param_11);
        float param_12 = mix(opacitySoftZScale, opacitySoftZScale * 500.0, gunParticle);
        opacitySoftZScale = saturate(param_12);
        vec3 _877 = final.xyz * vec3(vp_emissiveMult);
        final = vec4(_877.x, _877.y, _877.z, final.w);
        final.w *= opacitySoftZScale;
        vec3 _890 = final.xyz * vofi_Color.xyz;
        final = vec4(_890.x, _890.y, _890.z, final.w);
        float param_13 = vofi_Color.w;
        final.w = mix(final.w - (1.0 - sqrt(saturate(param_13))), final.w * vofi_Color.w, alphaFade);
        final.w *= alphaMul;
        vec3 _918 = final.xyz * diffuse_lighting;
        final = vec4(_918.x, _918.y, _918.z, final.w);
    }
    vec3 _934 = mix(final.xyz * rp_emissiveMult, final.xyz * _viewUniforms.particlemult.x, vec3(1.0 - mtl.particleFade_emissive_pad.z));
    final = vec4(_934.x, _934.y, _934.z, final.w);
    vec2 tc_1 = gl_FragCoord.xy * _viewUniforms.fragmentpositiontoviewtexture.zw;
    float ndcZ = gl_FragCoord.z;
    vec4 localLightScattering = vec4(0.0);
    float sunVolumeShadows = 1.0;
    float param_14 = _viewUniforms.fogparms.w;
    uint scatteringType = asuint(param_14);
    if ((scatteringType & 6u) != 0u)
    {
        vec2 tcLocalScattering = tc_1 + vec2(0.0);
        vec3 volumeRes = _viewUniforms.lightscatteringres.xyz;
        float zNear = 0.100000001490116119384765625;
        float zFar = _viewUniforms.lightscatteringparms.y;
        float zSlices = _viewUniforms.lightscatteringres.z;
        float volumeZ = 0.0;
        float param_15 = ndcZ;
        vec4 param_16 = _viewUniforms.projectionmatrixz;
        float param_17 = 1.0;
        bool param_18 = false;
        float linearZ = GetLinearDepth(param_15, param_16, param_17, param_18);
        volumeZ = pow(max(0.0, (linearZ - zNear) / (zFar - zNear)), 0.5);
        volumeZ = (volumeZ * (zSlices - 1.0)) / zSlices;
        vec4 tcVolume = vec4(tcLocalScattering, volumeZ, 0.0);
        vec3 _1031 = textureLod(samp_finallightscatteringpacked0map, vec4(tcVolume.xyz, 0.0).xyz, vec4(tcVolume.xyz, 0.0).w).xyz;
        localLightScattering = vec4(_1031.x, _1031.y, _1031.z, localLightScattering.w);
        vec2 finalLightScatteringPacked1 = textureLod(samp_finallightscatteringpacked1map, vec4(tcVolume.xyz, 0.0).xyz, vec4(tcVolume.xyz, 0.0).w).xy;
        localLightScattering.w = finalLightScatteringPacked1.x;
        sunVolumeShadows = finalLightScatteringPacked1.y;
    }
    if ((scatteringType & 2u) != 0u)
    {
        vec4 scatterParms = vec4(0.0);
        vec3 camPos = _viewUniforms.globalvieworigin.xyz;
        float param_19 = ndcZ;
        vec4 param_20 = _viewUniforms.projectionmatrixz;
        float param_21 = 1.0;
        bool param_22 = false;
        float linearZ_1 = GetLinearDepth(param_19, param_20, param_21, param_22);
        vec3 frustumVecX0 = mix(_viewUniforms.frustumvectl.xyz, _viewUniforms.frustumvectr.xyz, vec3(tc_1.x * _viewUniforms.resolutionscale.z));
        vec3 frustumVecX1 = mix(_viewUniforms.frustumvecbl.xyz, _viewUniforms.frustumvecbr.xyz, vec3(tc_1.x * _viewUniforms.resolutionscale.z));
        vec3 frustumVec = mix(frustumVecX1, frustumVecX0, vec3(1.0 - (tc_1.y * _viewUniforms.resolutionscale.w)));
        vec4 skylightingInputsLUT = vec4(0.0);
        vec3 viewNormalized = normalize(frustumVec);
        float param_23 = viewNormalized.z;
        skylightingInputsLUT.x = clamp(fastAcos(param_23) / 3.1415927410125732421875, 0.00390625, 0.99609375);
        float param_24 = viewNormalized.y;
        float param_25 = viewNormalized.x;
        skylightingInputsLUT.y = fastAtan2(param_24, param_25) / 6.283185482025146484375;
        skylightingInputsLUT.z = sqrt(linearZ_1 * _viewUniforms.znearfar.w);
        skylightingInputsLUT.z = clamp(skylightingInputsLUT.z, 0.015625, 0.984375);
        vec3 _1165 = textureLod(samp_skylightinglutmap, skylightingInputsLUT.xyz, skylightingInputsLUT.w).xyz;
        scatterParms = vec4(_1165.x, _1165.y, _1165.z, scatterParms.w);
        vec3 _1174 = final.xyz + (scatterParms.xyz * sunVolumeShadows);
        final = vec4(_1174.x, _1174.y, _1174.z, final.w);
    }
    if ((scatteringType & 4u) != 0u)
    {
        vec3 _1190 = (final.xyz * localLightScattering.w) + localLightScattering.xyz;
        final = vec4(_1190.x, _1190.y, _1190.z, final.w);
    }
    out_FragColor0 = final;
    float param_26 = out_FragColor0.w;
    out_FragColor0.w = saturate(param_26);
    float param_27 = out_FragColor0.w;
    out_FragColor0.w = saturate(param_27);
    vec3 _1211 = out_FragColor0.xyz * out_FragColor0.w;
    out_FragColor0 = vec4(_1211.x, _1211.y, _1211.z, out_FragColor0.w);
    out_FragColor1 = vec4(0.0);
    out_FragColor2 = vec4(0.0);
    if (_viewUniforms.watervolumeviewparms.w > 0.0)
    {
        vec2 tc_2 = gl_FragCoord.xy * _viewUniforms.fragmentpositiontoviewtexture.xy;
        bool beforeWater = (gl_FragCoord.z < textureLod(samp_watergbufferdepthmap, vec4(tc_2, 0.0, 0.0).xy, vec4(tc_2, 0.0, 0.0).w).x) ? true : false;
        if (beforeWater == false)
        {
            out_FragColor1 = out_FragColor0;
        }
        out_FragColor0 *= float(beforeWater == true);
        out_FragColor2.x = out_FragColor0.w;
    }
    out_FragColor2.w = out_FragColor0.w;
}


