

layout(location = 0) out vec3 gbuffer_data_0;
layout(location = 1) out vec4 gbuffer_data_1;
layout(location = 2) out vec4 gbuffer_data_2;
vec2 encodeNormal(in vec3 normal)
{
    normal.xy /= abs(normal.x) + abs(normal.y) + abs(normal.z);
    return (normal.z <= 0.0 ? (1.0 - abs(normal.yx)) * vec2(normal.x >= 0.0 ? 1.0 : -1.0, normal.y >= 0.0 ? 1.0 : -1.0)
                            : normal.xy) *
               0.5 +
           0.5;
}
float getMaterialProperties(int materialIndex)
{
    // Reflectance, Smoothness, Subsurface amounts, and Porosity
    switch (materialIndex)
    {
    case 4: // Fabric
        return 0.25;
    case 7: // Crystals
        return 0.5;
    case 9: // Ice
        return 0.25;
    case 2003: // Foliage (Leaves)
    case 2013: // Foliage (Modded & Fallback)
        return 0.5;
    case 2001: // Foliage (Tall Flowers)
    case 2002: // Foliage (Tall Flowers)
    case 2004: // Foliage (Tall Flowers)
    case 2005: // Foliage (Other Plants)
    case 2011: // Foliage (Modded & Fallback)
        return 0.75;
    case 10010: // Banners
        return 0.254;
    default:
        return 0.0;
        // Default value if index is out of range
    }
}
float encodeVec2(vec2 a)
{
    vec2 t = floor(a * 255.0);
    return (t.x + t.y * 256.0) / 65535.0;
}
float luma(vec3 color)
{
    return dot(color, vec3(0.299, 0.587, 0.114));
}
vec3 toLinear(vec3 sRGB)
{
    return sRGB * (sRGB * (sRGB * 0.305306011 + 0.682171111) + 0.012522878);
}
float remap(const float originalValue, const float originalMin, const float originalMax, const float newMin, const float newMax)
{
    return newMin + (((originalValue - originalMin) / (originalMax - originalMin)) * (newMax - newMin));
}
void voxy_emitFragment(VoxyFragmentParameters parameters)
{
    // Get base properties

    vec3 base_color = toLinear(parameters.sampledColour.rgb * parameters.tinting.rgb);

    // from Cortex
    vec3 normal = vec3(
                      uint((parameters.face >> 1) == 2),
                      uint((parameters.face >> 1) == 0),
                      uint((parameters.face >> 1) == 1)) *
                  (float(int(parameters.face) & 1) * 2.0 - 1.0);

    float labvalue = float(getMaterialProperties(int(parameters.customId)));
   float  sss = labvalue;
    float modifier = remap(luma(parameters.sampledColour.rgb), 0, 1, 0.5, 1.0);
    if (sss <= 0.0)
    {
        sss = (16.0 + 47.0 * mix(labvalue * 1.2, labvalue, modifier)) * (1.0 / 255.0);
    }
    else
    {
        sss = (64.5 + 190.5 * mix(sss * 1.2, sss, modifier)) * (1.0 / 255.0);
    }

    // Encode gbuffer data
    gbuffer_data_0 = base_color;
    gbuffer_data_1 = vec4(encodeNormal(normal), encodeVec2(clamp(parameters.lightMap, 0.0, 1.0)), encodeVec2(vec2(1, sss)));
    gbuffer_data_2.r = encodeVec2(vec2(0.04, 0.1) * remap(luma(parameters.sampledColour.rgb), 0, 1, 0.5, 1.0));
    gbuffer_data_2.gba = vec3(1);
}