#pragma clang diagnostic ignored "-Wmissing-prototypes"

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

using namespace metal;

struct Globals
{
    float4x4 uMVP;
    float4x4 uModel;
    packed_float3 uCamPos;
    float uLight;
    packed_float3 uFog;
    float uFogStart;
    float uFogEnd;
    float4 uTint;
    float uFlash;
    int uDynLightCount;
    float4 uDynLightPosRadius0;
    float4 uDynLightPosRadius1;
    float4 uDynLightPosRadius2;
    float4 uDynLightPosRadius3;
    float4 uDynLightColor0;
    float4 uDynLightColor1;
    float4 uDynLightColor2;
    float4 uDynLightColor3;
};

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

struct main0_in
{
    float3 vNormal [[user(locn0)]];
    float4 vColor [[user(locn1)]];
    float vDist [[user(locn2)]];
    float3 vWorld [[user(locn3)]];
};

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)]])
{
    main0_out out = {};
    float3 N = fast::normalize(in.vNormal);
    float lambert = 0.5 + (0.5 * fast::max(dot(N, float3(0.3577708899974822998046875, 0.89442718029022216796875, 0.2683281600475311279296875)), 0.0));
    float3 c = ((in.vColor.xyz * _62.uTint.xyz) * lambert) * _62.uLight;
    if (_62.uDynLightCount > 0)
    {
        float3 param = in.vWorld;
        float3 dyn = dynamicLighting(param, _62);
        c = fast::max(c, ((in.vColor.xyz * _62.uTint.xyz) * lambert) * dyn);
        c += ((((in.vColor.xyz * _62.uTint.xyz) * lambert) * dyn) * 0.07999999821186065673828125);
    }
    c = mix(c, float3(1.0), float3(_62.uFlash));
    float fog = fast::clamp((in.vDist - _62.uFogStart) / fast::max(1.0, _62.uFogEnd - _62.uFogStart), 0.0, 1.0);
    c = mix(c, float3(_62.uFog), float3(fog));
    out.FragColor = float4(c, in.vColor.w * _62.uTint.w);
    return out;
}

