loadMaterial( materialIndex ) {

    		const parser = this;
    		const json = this.json;
    		const extensions = this.extensions;
    		const materialDef = json.materials[ materialIndex ];

    		let materialType;
    		const materialParams = {};
    		const materialExtensions = materialDef.extensions || {};

    		const pending = [];

    		if ( materialExtensions[ EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS ] ) {

    			const sgExtension = extensions[ EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS ];
    			materialType = sgExtension.getMaterialType();
    			pending.push( sgExtension.extendParams( materialParams, materialDef, parser ) );

    		} else if ( materialExtensions[ EXTENSIONS.KHR_MATERIALS_UNLIT ] ) {

    			const kmuExtension = extensions[ EXTENSIONS.KHR_MATERIALS_UNLIT ];
    			materialType = kmuExtension.getMaterialType();
    			pending.push( kmuExtension.extendParams( materialParams, materialDef, parser ) );

    		} else {

    			// Specification:
    			// https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#metallic-roughness-material

    			const metallicRoughness = materialDef.pbrMetallicRoughness || {};

    			materialParams.color = new Color( 1.0, 1.0, 1.0 );
    			materialParams.opacity = 1.0;

    			if ( Array.isArray( metallicRoughness.baseColorFactor ) ) {

    				const array = metallicRoughness.baseColorFactor;

    				materialParams.color.fromArray( array );
    				materialParams.opacity = array[ 3 ];

    			}

    			if ( metallicRoughness.baseColorTexture !== undefined ) {

    				pending.push( parser.assignTexture( materialParams, 'map', metallicRoughness.baseColorTexture ) );

    			}

    			materialParams.metalness = metallicRoughness.metallicFactor !== undefined ? metallicRoughness.metallicFactor : 1.0;
    			materialParams.roughness = metallicRoughness.roughnessFactor !== undefined ? metallicRoughness.roughnessFactor : 1.0;

    			if ( metallicRoughness.metallicRoughnessTexture !== undefined ) {

    				pending.push( parser.assignTexture( materialParams, 'metalnessMap', metallicRoughness.metallicRoughnessTexture ) );
    				pending.push( parser.assignTexture( materialParams, 'roughnessMap', metallicRoughness.metallicRoughnessTexture ) );

    			}

    			materialType = this._invokeOne( function ( ext ) {

    				return ext.getMaterialType && ext.getMaterialType( materialIndex );

    			} );

    			pending.push( Promise.all( this._invokeAll( function ( ext ) {

    				return ext.extendMaterialParams && ext.extendMaterialParams( materialIndex, materialParams );

    			} ) ) );

    		}

    		if ( materialDef.doubleSided === true ) {

    			materialParams.side = DoubleSide;

    		}

    		const alphaMode = materialDef.alphaMode || ALPHA_MODES.OPAQUE;

    		if ( alphaMode === ALPHA_MODES.BLEND ) {

    			materialParams.transparent = true;

    			// See: https://github.com/mrdoob/three.js/issues/17706
    			materialParams.depthWrite = false;

    		} else {

    			materialParams.format = RGBFormat;
    			materialParams.transparent = false;

    			if ( alphaMode === ALPHA_MODES.MASK ) {

    				materialParams.alphaTest = materialDef.alphaCutoff !== undefined ? materialDef.alphaCutoff : 0.5;

    			}

    		}

    		if ( materialDef.normalTexture !== undefined && materialType !== MeshBasicMaterial ) {

    			pending.push( parser.assignTexture( materialParams, 'normalMap', materialDef.normalTexture ) );

    			materialParams.normalScale = new Vector2( 1, 1 );

    			if ( materialDef.normalTexture.scale !== undefined ) {

    				const scale = materialDef.normalTexture.scale;

    				materialParams.normalScale.set( scale, scale );

    			}

    		}

    		if ( materialDef.occlusionTexture !== undefined && materialType !== MeshBasicMaterial ) {

    			pending.push( parser.assignTexture( materialParams, 'aoMap', materialDef.occlusionTexture ) );

    			if ( materialDef.occlusionTexture.strength !== undefined ) {

    				materialParams.aoMapIntensity = materialDef.occlusionTexture.strength;

    			}

    		}

    		if ( materialDef.emissiveFactor !== undefined && materialType !== MeshBasicMaterial ) {

    			materialParams.emissive = new Color().fromArray( materialDef.emissiveFactor );

    		}

    		if ( materialDef.emissiveTexture !== undefined && materialType !== MeshBasicMaterial ) {

    			pending.push( parser.assignTexture( materialParams, 'emissiveMap', materialDef.emissiveTexture ) );

    		}

    		return Promise.all( pending ).then( function () {

    			let material;

    			if ( materialType === GLTFMeshStandardSGMaterial ) {

    				material = extensions[ EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS ].createMaterial( materialParams );

    			} else {

    				material = new materialType( materialParams );

    			}

    			if ( materialDef.name ) material.name = materialDef.name;

    			// baseColorTexture, emissiveTexture, and specularGlossinessTexture use sRGB encoding.
    			if ( material.map ) material.map.encoding = sRGBEncoding;
    			if ( material.emissiveMap ) material.emissiveMap.encoding = sRGBEncoding;

    			assignExtrasToUserData( material, materialDef );

    			parser.associations.set( material, { materials: materialIndex } );

    			if ( materialDef.extensions ) addUnknownExtensionsToUserData( extensions, material, materialDef );

    			return material;

    		} );

    	}
Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#materials
@param {number} materialIndex
@return {Promise<Material>}