material {
    name : unlit_fade,
    requires : [ uv0, uv1, color ],
    shadingModel : ${SHADINGMODEL},
    blending : ${BLENDING},
    doubleSided : ${DOUBLESIDED},
    transparency : ${TRANSPARENCY},
    flipUV : false,
    specularAmbientOcclusion : simple,
    specularAntiAliasing : true,
    clearCoatIorChange : false,
    reflections : screenspace,
    parameters : [

        { type : float3, name : specularFactor },
        { type : float, name : glossinessFactor },

        // Base Color
        { type : int, name : baseColorIndex },
        { type : float4, name : baseColorFactor },
        { type : sampler2d, name : baseColorMap },
        { type : mat3, name : baseColorUvMatrix, precision: high },

        // Metallic-Roughness Map
        { type : int, name : metallicRoughnessIndex },
        { type : float, name : metallicFactor },
        { type : float, name : roughnessFactor },
        { type : sampler2d, name : metallicRoughnessMap },
        { type : mat3, name : metallicRoughnessUvMatrix, precision: high },

        // Normal Map
        { type : int, name : normalIndex },
        { type : float, name : normalScale },
        { type : sampler2d, name : normalMap },
        { type : mat3, name : normalUvMatrix, precision: high },

        // Ambient Occlusion
        { type : int, name : aoIndex },
        { type : float, name : aoStrength },
        { type : sampler2d, name : occlusionMap },
        { type : mat3, name : occlusionUvMatrix, precision: high },

        // Emissive Map
        { type : int, name : emissiveIndex },
        { type : float3, name : emissiveFactor },
        { type : float, name : emissiveStrength },
        { type : sampler2d, name : emissiveMap },
        { type : mat3, name : emissiveUvMatrix, precision: high },

        // Clear coat
        { type : float, name : clearCoatFactor },
        { type : float, name : clearCoatRoughnessFactor },
        { type : int, name : clearCoatIndex },
        { type : sampler2d, name : clearCoatMap },
        { type : mat3, name : clearCoatUvMatrix, precision: high },
        { type : int, name : clearCoatRoughnessIndex },
        { type : sampler2d, name : clearCoatRoughnessMap },
        { type : mat3, name : clearCoatRoughnessUvMatrix, precision: high },
        { type : int, name : clearCoatNormalIndex },
        { type : sampler2d, name : clearCoatNormalMap },
        { type : mat3, name : clearCoatNormalUvMatrix, precision: high },
        { type : float, name : clearCoatNormalScale },

        // Reflectance
        { type : float, name : reflectance }

        ${CUSTOM_PARAMS}
    ],
}

vertex {
  void materialVertex(inout MaterialVertexInputs material) {
      ${CUSTOM_VERTEX}
    }
}

fragment {
    void material(inout MaterialInputs material) {
        highp float2 uvs[2];
        uvs[0] = getUV0();
        uvs[1] = getUV1();

        #if !defined(SHADING_MODEL_UNLIT)
            if (materialParams.normalIndex > -1) {
                highp float2 uv = uvs[materialParams.normalIndex];
                uv = (vec3(uv, 1.0) * materialParams.normalUvMatrix).xy;
                material.normal = texture(materialParams_normalMap, uv).xyz * 2.0 - 1.0;
                material.normal.xy *= materialParams.normalScale;
            }
            #if defined(SHADING_MODEL_LIT)
            if (materialParams.clearCoatNormalIndex > -1) {
                highp float2 uv = uvs[materialParams.clearCoatNormalIndex];
                uv = (vec3(uv, 1.0) * materialParams.clearCoatNormalUvMatrix).xy;
                material.clearCoatNormal = texture(materialParams_clearCoatNormalMap, uv).xyz * 2.0 - 1.0;
                material.clearCoatNormal.xy *= materialParams.clearCoatNormalScale;
            }
            #endif
        #endif

        prepareMaterial(material);
        material.baseColor = materialParams.baseColorFactor;

        if (materialParams.baseColorIndex > -1) {
            highp float2 uv = uvs[materialParams.baseColorIndex];
            uv = (vec3(uv, 1.0) * materialParams.baseColorUvMatrix).xy;
            material.baseColor *= texture(materialParams_baseColorMap, uv);
        }

        #if defined(BLEND_MODE_TRANSPARENT)
            material.baseColor.rgb *= material.baseColor.a;
        #endif

        material.baseColor *= getColor();

        #if !defined(SHADING_MODEL_UNLIT)

            #if defined(SHADING_MODEL_LIT)
                material.roughness = materialParams.roughnessFactor;
                material.metallic = materialParams.metallicFactor;

                // KHR_materials_clearcoat forbids clear coat from
                // being applied in the specular/glossiness model
                material.clearCoat = materialParams.clearCoatFactor;
                material.clearCoatRoughness = materialParams.clearCoatRoughnessFactor;

                if (materialParams.clearCoatIndex > -1) {
                    highp float2 uv = uvs[materialParams.clearCoatIndex];
                    uv = (vec3(uv, 1.0) * materialParams.clearCoatUvMatrix).xy;
                    material.clearCoat *= texture(materialParams_clearCoatMap, uv).r;
                }
                if (materialParams.clearCoatRoughnessIndex > -1) {
                    highp float2 uv = uvs[materialParams.clearCoatRoughnessIndex];
                    uv = (vec3(uv, 1.0) * materialParams.clearCoatRoughnessUvMatrix).xy;
                    material.clearCoatRoughness *= texture(materialParams_clearCoatRoughnessMap, uv).g;
                }
            #endif

            material.emissive = vec4(materialParams.emissiveStrength *
                    materialParams.emissiveFactor.rgb, 0.0);

            #if defined(SHADING_MODEL_SPECULAR_GLOSSINESS)
                material.glossiness = materialParams.glossinessFactor;
                material.specularColor = materialParams.specularFactor;
            #else
                material.reflectance = materialParams.reflectance;
            #endif

            if (materialParams.metallicRoughnessIndex > -1) {
                highp float2 uv = uvs[materialParams.metallicRoughnessIndex];
                uv = (vec3(uv, 1.0) * materialParams.metallicRoughnessUvMatrix).xy;

                #if defined(SHADING_MODEL_SPECULAR_GLOSSINESS)
                    vec4 sg = texture(materialParams_metallicRoughnessMap, uv);
                    material.specularColor *= sg.rgb;
                    material.glossiness *= sg.a;
                #else
                    vec4 mr = texture(materialParams_metallicRoughnessMap, uv);
                    material.roughness *= mr.g;
                    material.metallic *= mr.b;
                #endif
            }

            if (materialParams.aoIndex > -1) {
                highp float2 uv = uvs[materialParams.aoIndex];
                uv = (vec3(uv, 1.0) * materialParams.occlusionUvMatrix).xy;
                float occlusion = texture(materialParams_occlusionMap, uv).r;
                material.ambientOcclusion = 1.0 + materialParams.aoStrength * (occlusion - 1.0);
            }
            if (materialParams.emissiveIndex > -1) {
                highp float2 uv = uvs[materialParams.emissiveIndex];
                uv = (vec3(uv, 1.0) * materialParams.emissiveUvMatrix).xy;
                material.emissive.rgb *= texture(materialParams_emissiveMap, uv).rgb;
            }
        #endif

        ${CUSTOM_FRAGMENT}
    }
}
