#define MATERIAL_WATER 4
#define MATERIAL_SSS_WEAK 5
#define MATERIAL_SSS_STRONG 6
#define MATERIAL_TALL_PLANT_LOWER 7
#define MATERIAL_TALL_PLANT_UPPER 8
#define MATERIAL_SHORT_PLANT 9
#define MATERIAL_LEAVES 10

float hardcoded_smoothness(float Material) {
    int Mat = int(Material);
    switch (Mat) {
        case 4:
        return 0.85;
    }
    return 0;
}

float get_smoothness(vec2 Texcoord, float Material) {
    float HS = hardcoded_smoothness(Material);
    if (HS != 0) return HS;

    #ifdef DEFERRED
    float Smoothness = unpackUnorm2x8(texture(colortex1, Texcoord).z).x;
    #else
    float Smoothness = texture(specular, Texcoord).r;
    #endif
    return Smoothness;
}

float smoothness_to_roughness(float Smoothness) {
    return pow2(1 - Smoothness);
}

float hardcoded_f0(float Material) {
    int Mat = int(Material);
    switch (Mat) {
        case 4:
        return 0.02;
    }
    return -1;
}

const mat2x3 hardcoded_metals[8] = mat2x3[8](
        mat2x3(vec3(2.9114, 2.9497, 2.5845), vec3(3.0893, 2.9318, 2.7670)),
        mat2x3(vec3(0.18299, 0.42108, 1.3734), vec3(3.4242, 2.3459, 1.7704)),
        mat2x3(vec3(1.3456, 0.96521, 0.61722), vec3(7.4746, 6.3995, 5.3031)),
        mat2x3(vec3(3.1071, 3.1812, 2.3230), vec3(3.3314, 3.3291, 3.1350)),
        mat2x3(vec3(0.27105, 0.67693, 1.3164), vec3(3.6092, 2.6248, 2.2921)),
        mat2x3(vec3(1.9100, 1.8300, 1.4400), vec3(3.5100, 3.4000, 3.1800)),
        mat2x3(vec3(2.3757, 2.0847, 1.8453), vec3(4.2655, 3.7153, 3.1365)),
        mat2x3(vec3(0.15943, 0.14512, 0.13547), vec3(3.9291, 3.1900, 2.3808))
    );

mat2x3 get_f0(vec2 Texcoord, float Material, vec3 Color, out bool IsMetal, out bool IsHardcodedMetal) {
    float F0 = hardcoded_f0(Material);
    if (F0 < 0) {
        #ifdef DEFERRED
        F0 = unpackUnorm2x8(texture(colortex1, Texcoord).z).y;
        #else
        F0 = texture(specular, Texcoord).g;
        #endif
    }
    uint F0ui = uint(F0 * 255);
    IsMetal = F0ui >= 230;
    IsHardcodedMetal = IsMetal && F0ui <= 237;
    if (F0ui == 255) {
        return mat2x3(Color, vec3(0));
    }
    else if (IsHardcodedMetal) {
        return hardcoded_metals[F0ui - 230];
    }
    else {
        return mat2x3(vec3(F0), vec3(0));
    }
}

// Only for use in gbuffers
vec3 get_normal(vec2 Texcoord) {
    vec3 Normal;
    Normal.xy = texture(normals, Texcoord.xy).xy * 2 - 1;
    Normal.z = sqrt(1 - dot(Normal.xy, Normal.xy));
    return Normal;
}
