#pragma clang diagnostic ignored "-Wmissing-prototypes"

#include <metal_stdlib>
#include <simd/simd.h>

using namespace metal;

struct Globals
{
    float4x4 uMVP;
    packed_float3 uChunkOrigin;
    float uDayLight;
    float uAmbient;
    float uAlphaCutoff;
    char _m5_pad[8];
    packed_float3 uFogColor;
    float uFogStart;
    float uFogEnd;
    int uDynLightCount;
    float4 uDynLightPosRadius0;
    float4 uDynLightPosRadius1;
    float4 uDynLightPosRadius2;
    float4 uDynLightPosRadius3;
    float4 uDynLightColor0;
    float4 uDynLightColor1;
    float4 uDynLightColor2;
    float4 uDynLightColor3;
    int uFogMode;
    float uFogDensity;
    float uFogHeightFalloff;
    float uTime;
    float uWaveAmp;
    float3 uCamPos;
};

struct main0_out
{
    float4 FragColor [[color(0)]];
};

struct main0_in
{
    float2 vUV [[user(locn0)]];
    float vLayer [[user(locn1), flat]];
    float vShade [[user(locn2)]];
    float vDist [[user(locn3)]];
    float3 vWorld [[user(locn4)]];
    float vLiquid [[user(locn5), flat]];
};

static inline __attribute__((always_inline))
float3 pointLight(thread const float3& p, thread const float4& posRadius, thread const float4& colorIntensity)
{
    float3 d = p - posRadius.xyz;
    float a = fast::max(0.0, 1.0 - (dot(d, d) / fast::max(posRadius.w * posRadius.w, 0.001000000047497451305389404296875)));
    return colorIntensity.xyz * ((colorIntensity.w * a) * a);
}

static inline __attribute__((always_inline))
float3 dynamicLighting(thread const float3& p, constant Globals& _62)
{
    float3 l = float3(0.0);
    if (_62.uDynLightCount > 0)
    {
        float3 param = p;
        float4 param_1 = _62.uDynLightPosRadius0;
        float4 param_2 = _62.uDynLightColor0;
        l += pointLight(param, param_1, param_2);
    }
    if (_62.uDynLightCount > 1)
    {
        float3 param_3 = p;
        float4 param_4 = _62.uDynLightPosRadius1;
        float4 param_5 = _62.uDynLightColor1;
        l += pointLight(param_3, param_4, param_5);
    }
    if (_62.uDynLightCount > 2)
    {
        float3 param_6 = p;
        float4 param_7 = _62.uDynLightPosRadius2;
        float4 param_8 = _62.uDynLightColor2;
        l += pointLight(param_6, param_7, param_8);
    }
    if (_62.uDynLightCount > 3)
    {
        float3 param_9 = p;
        float4 param_10 = _62.uDynLightPosRadius3;
        float4 param_11 = _62.uDynLightColor3;
        l += pointLight(param_9, param_10, param_11);
    }
    return fast::min(l, float3(2.0));
}

fragment main0_out main0(main0_in in [[stage_in]], constant Globals& _62 [[buffer(0)]], texture2d_array<float> uAtlas [[texture(0)]], sampler uAtlasSmplr [[sampler(0)]])
{
    main0_out out = {};
    float2 uv = in.vUV;
    bool _159 = in.vLiquid > 0.5;
    bool _167;
    if (_159)
    {
        _167 = _62.uWaveAmp > 0.0;
    }
    else
    {
        _167 = _159;
    }
    if (_167)
    {
        uv += float2(_62.uTime * 0.0199999995529651641845703125, _62.uTime * 0.0130000002682209014892578125);
    }
    float3 _193 = float3(uv, in.vLayer);
    float4 tex = uAtlas.sample(uAtlasSmplr, _193.xy, uint(rint(_193.z)));
    if (tex.w < _62.uAlphaCutoff)
    {
        discard_fragment();
    }
    float3 color = tex.xyz * in.vShade;
    bool _211 = in.vLiquid > 0.5;
    bool _217;
    if (_211)
    {
        _217 = _62.uWaveAmp > 0.0;
    }
    else
    {
        _217 = _211;
    }
    if (_217)
    {
        float3 toCam = fast::normalize(_62.uCamPos - in.vWorld);
        float grazing = 1.0 - fast::clamp(abs(toCam.y), 0.0, 1.0);
        color *= (1.0 - ((0.300000011920928955078125 * grazing) * grazing));
    }
    if (_62.uDynLightCount > 0)
    {
        float3 param = in.vWorld;
        float3 dyn = dynamicLighting(param, _62);
        color = fast::max(color, tex.xyz * dyn);
        color += ((tex.xyz * dyn) * 0.100000001490116119384765625);
    }
    float fog;
    if (_62.uFogMode == 1)
    {
        float hf = exp2(-fast::min(fast::max(in.vWorld.y - 62.0, 0.0) * _62.uFogHeightFalloff, 1.2000000476837158203125));
        float d = (fast::max(in.vDist - (_62.uFogEnd * 0.5), 0.0) * _62.uFogDensity) * hf;
        fog = 1.0 - exp2((-d) * d);
        fog = fast::max(fog, fast::clamp((in.vDist - (_62.uFogEnd * 0.85000002384185791015625)) / (_62.uFogEnd * 0.1500000059604644775390625), 0.0, 1.0));
    }
    else
    {
        fog = fast::clamp((in.vDist - _62.uFogStart) / fast::max(_62.uFogEnd - _62.uFogStart, 0.001000000047497451305389404296875), 0.0, 1.0);
    }
    color = mix(color, float3(_62.uFogColor), float3(fog));
    out.FragColor = float4(color, tex.w);
    return out;
}

