/// <summary>
            ///     To the helix material.
            /// </summary>
            /// <param name="material">The material.</param>
            /// <returns></returns>
            /// <exception cref="System.NotSupportedException">Shading Mode {material.ShadingMode}</exception>
            protected virtual KeyValuePair <global::Assimp.Material, MaterialCore> OnCreateHelixMaterial(global::Assimp.Material material)
            {
                MaterialCore core = null;

                if (!material.HasShadingMode)
                {
                    if (material.HasNonTextureProperty(GLTFMatKeys.AI_MATKEY_GLTF_METALLIC_FACTOR) ||
                        material.HasNonTextureProperty(GLTFMatKeys.AI_MATKEY_GLTF_ROUGHNESS_FACTOR) ||
                        material.HasNonTextureProperty(GLTFMatKeys.AI_MATKEY_GLTF_BASECOLOR_FACTOR))
                    {
                        material.ShadingMode = ShadingMode.Fresnel;
                    }
                    else if (material.HasColorSpecular || material.HasColorDiffuse || material.HasTextureDiffuse)
                    {
                        material.ShadingMode = ShadingMode.Blinn;
                    }
                    else
                    {
                        material.ShadingMode = ShadingMode.Gouraud;
                    }
                }

                var mode = material.ShadingMode;

                if (Configuration.ImportMaterialType != MaterialType.Auto)
                {
                    switch (Configuration.ImportMaterialType)
                    {
                    case MaterialType.BlinnPhong:
                        mode = ShadingMode.Blinn;
                        break;

                    case MaterialType.Diffuse:
                        mode = ShadingMode.Gouraud;
                        break;

                    case MaterialType.PBR:
                        mode = ShadingMode.Fresnel;
                        break;

                    case MaterialType.VertexColor:
                        core = new ColorMaterialCore();
                        break;

                    case MaterialType.Normal:
                        core = new NormalMaterialCore();
                        break;

                    case MaterialType.Position:
                        core = new PositionMaterialCore();
                        break;
                    }
                }
                if (core == null)
                {
                    switch (mode)
                    {
                    case ShadingMode.Blinn:
                    case ShadingMode.Phong:
                    case ShadingMode.None:
                        core = OnCreatePhongMaterial(material);
                        break;

                    case ShadingMode.CookTorrance:
                    case ShadingMode.Fresnel:
                    case ShadingMode.OrenNayar:
                        core = OnCreatePBRMaterial(material);
                        break;

                    case ShadingMode.Gouraud:
                        var diffuse = new DiffuseMaterialCore
                        {
                            DiffuseColor = material.ColorDiffuse.ToSharpDXColor4()
                        };
                        if (material.HasOpacity)
                        {
                            var c = diffuse.DiffuseColor;
                            c.Alpha = material.Opacity;
                            diffuse.DiffuseColor = c;
                        }

                        if (material.HasTextureDiffuse)
                        {
                            diffuse.DiffuseMap         = LoadTexture(material.TextureDiffuse.FilePath);
                            diffuse.DiffuseMapFilePath = material.TextureDiffuse.FilePath;
                        }
                        if (material.ShadingMode == ShadingMode.Flat)
                        {
                            diffuse.EnableFlatShading = true;
                        }
                        core = diffuse;
                        break;

                    case ShadingMode.Flat:
                        core = OnCreatePhongMaterial(material);
                        if (core is PhongMaterialCore p)
                        {
                            p.EnableFlatShading = true;
                        }
                        break;

                    default:
                        switch (Configuration.ImportMaterialType)
                        {
                        case MaterialType.Position:
                            core = new PositionMaterialCore();
                            break;

                        case MaterialType.Normal:
                            core = new NormalMaterialCore();
                            break;

                        default:
                            Log(HelixToolkit.Logger.LogLevel.Warning, $"Shading Mode is not supported:{material.ShadingMode}");
                            core = new DiffuseMaterialCore()
                            {
                                DiffuseColor = Color.Red, EnableUnLit = true
                            };
                            break;
                        }
                        break;
                    }
                }

                if (core != null)
                {
                    core.Name = string.IsNullOrEmpty(material.Name) ? $"Material_{Interlocked.Increment(ref MaterialIndexForNoName)}" : material.Name;
                }
                return(new KeyValuePair <global::Assimp.Material, MaterialCore>(material, core));
            }
            /// <summary>
            ///     To the phong material.
            /// </summary>
            /// <param name="material">The material.</param>
            /// <returns></returns>
            protected virtual PhongMaterialCore OnCreatePhongMaterial(global::Assimp.Material material)
            {
                var phong = new PhongMaterialCore
                {
                    AmbientColor    = (material.HasColorAmbient && !configuration.IgnoreAmbientColor) ? material.ColorAmbient.ToSharpDXColor4() : Color.Black,
                    DiffuseColor    = material.HasColorDiffuse ? material.ColorDiffuse.ToSharpDXColor4() : Color.White,
                    SpecularColor   = material.HasColorSpecular ? material.ColorSpecular.ToSharpDXColor4() : Color.Black,
                    EmissiveColor   = (material.HasColorEmissive && !configuration.IgnoreEmissiveColor) ? material.ColorEmissive.ToSharpDXColor4() : Color.Black,
                    ReflectiveColor = material.HasColorReflective
                        ? material.ColorReflective.ToSharpDXColor4()
                        : Color.Black,
                    SpecularShininess = material.Shininess
                };

                if (material.HasOpacity)
                {
                    var c = phong.DiffuseColor;
                    c.Alpha            = material.Opacity;
                    phong.DiffuseColor = c;
                }

                if (material.HasTextureDiffuse)
                {
                    phong.DiffuseMap         = LoadTexture(material.TextureDiffuse.FilePath);
                    phong.DiffuseMapFilePath = material.TextureDiffuse.FilePath;
                    var desc = Shaders.DefaultSamplers.LinearSamplerClampAni1;
                    desc.AddressU           = ToDXAddressMode(material.TextureDiffuse.WrapModeU);
                    desc.AddressV           = ToDXAddressMode(material.TextureDiffuse.WrapModeV);
                    phong.DiffuseMapSampler = desc;
                }

                if (material.HasTextureNormal)
                {
                    phong.NormalMap         = LoadTexture(material.TextureNormal.FilePath);
                    phong.NormalMapFilePath = material.TextureNormal.FilePath;
                }
                else if (material.HasTextureHeight)
                {
                    phong.NormalMap         = LoadTexture(material.TextureHeight.FilePath);
                    phong.NormalMapFilePath = material.TextureHeight.FilePath;
                }
                if (material.HasTextureSpecular)
                {
                    phong.SpecularColorMap         = LoadTexture(material.TextureSpecular.FilePath);
                    phong.SpecularColorMapFilePath = material.TextureSpecular.FilePath;
                }
                if (material.HasTextureDisplacement)
                {
                    phong.DisplacementMap         = LoadTexture(material.TextureDisplacement.FilePath);
                    phong.DisplacementMapFilePath = material.TextureDisplacement.FilePath;
                }

                if (material.HasTextureOpacity)
                {
                    phong.DiffuseAlphaMap         = LoadTexture(material.TextureOpacity.FilePath);
                    phong.DiffuseAlphaMapFilePath = material.TextureOpacity.FilePath;
                }
                if (material.HasTextureEmissive)
                {
                    phong.EmissiveMap         = LoadTexture(material.TextureEmissive.FilePath);
                    phong.EmissiveMapFilePath = material.TextureEmissive.FilePath;
                }

                if (material.HasNonTextureProperty(AiMatKeys.UVTRANSFORM_BASE))
                {
                    var values = material.GetNonTextureProperty(AiMatKeys.UVTRANSFORM_BASE).GetFloatArrayValue();
                    if (values != null && values.Length == 5)
                    {
                        phong.UVTransform = new UVTransform(values[0], new Vector2(values[1], values[2]), new Vector2(values[3], values[4]));
                    }
                }
                return(phong);
            }
            /// <summary>
            ///     To the PBR material.
            /// </summary>
            /// <param name="material">The material.</param>
            /// <returns></returns>
            protected virtual PBRMaterialCore OnCreatePBRMaterial(global::Assimp.Material material)
            {
                var pbr = new PBRMaterialCore
                {
                    AlbedoColor   = material.HasColorDiffuse ? material.ColorDiffuse.ToSharpDXColor4() : Color.Black,
                    EmissiveColor = material.HasColorEmissive && !Configuration.IgnoreEmissiveColor
                        ? material.ColorEmissive.ToSharpDXColor4()
                        : Color.Black,
                };

                if (material.HasNonTextureProperty(GLTFMatKeys.AI_MATKEY_GLTF_BASECOLOR_FACTOR))
                {
                    pbr.AlbedoColor = material.GetNonTextureProperty(GLTFMatKeys.AI_MATKEY_GLTF_BASECOLOR_FACTOR)
                                      .GetColor4DValue().ToSharpDXColor4();
                }
                if (material.HasNonTextureProperty(GLTFMatKeys.AI_MATKEY_GLTF_METALLIC_FACTOR))
                {
                    pbr.MetallicFactor = material.GetNonTextureProperty(GLTFMatKeys.AI_MATKEY_GLTF_METALLIC_FACTOR)
                                         .GetFloatValue();
                }
                if (material.HasColorAmbient)
                {
                    pbr.AmbientOcclusionFactor = material.ColorAmbient.R;
                }
                if (material.HasNonTextureProperty(GLTFMatKeys.AI_MATKEY_GLTF_ROUGHNESS_FACTOR))
                {
                    pbr.RoughnessFactor = material.GetNonTextureProperty(GLTFMatKeys.AI_MATKEY_GLTF_METALLIC_FACTOR)
                                          .GetFloatValue();
                }
                else if (material.HasColorSpecular && material.HasShininess)
                {
                    //Ref https://github.com/assimp/assimp/blob/master/code/glTF2Exporter.cpp
                    float specularIntensity = material.ColorSpecular.R * 0.2125f
                                              + material.ColorSpecular.G * 0.7154f + material.ColorSpecular.B * 0.0721f;
                    float normalizedShininess = (float)Math.Sqrt(material.Shininess / 1000);
                    normalizedShininess  = Math.Min(Math.Max(normalizedShininess, 0), 1f);
                    normalizedShininess *= specularIntensity;
                    pbr.RoughnessFactor  = 1 - normalizedShininess;
                }
                if (material.HasNonTextureProperty(GLTFMatKeys.AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS))
                {
                    var hasGlossiness = material.GetNonTextureProperty(GLTFMatKeys.AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS).GetBooleanValue();
                    if (hasGlossiness)
                    {
                        if (material.HasNonTextureProperty(GLTFMatKeys.AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS_GLOSSINESS_FACTOR))
                        {
                            pbr.ReflectanceFactor = material.GetNonTextureProperty(GLTFMatKeys.AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS_GLOSSINESS_FACTOR).GetFloatValue();
                        }
                        else if (material.HasShininess)
                        {
                            pbr.ReflectanceFactor = material.Shininess / 1000;
                        }
                    }
                }
                if (material.HasOpacity)
                {
                    var c = pbr.AlbedoColor;
                    c.Alpha         = material.Opacity;
                    pbr.AlbedoColor = c;
                }

                if (material.HasTextureDiffuse)
                {
                    pbr.AlbedoMap         = LoadTexture(material.TextureDiffuse.FilePath);
                    pbr.AlbedoMapFilePath = material.TextureDiffuse.FilePath;
                    var desc = Shaders.DefaultSamplers.LinearSamplerClampAni1;
                    desc.AddressU         = ToDXAddressMode(material.TextureDiffuse.WrapModeU);
                    desc.AddressV         = ToDXAddressMode(material.TextureDiffuse.WrapModeV);
                    pbr.SurfaceMapSampler = desc;
                }

                if (material.HasTextureNormal)
                {
                    pbr.NormalMap         = LoadTexture(material.TextureNormal.FilePath);
                    pbr.NormalMapFilePath = material.TextureNormal.FilePath;
                }
                else if (material.HasTextureHeight)
                {
                    pbr.NormalMap         = LoadTexture(material.TextureHeight.FilePath);
                    pbr.NormalMapFilePath = material.TextureHeight.FilePath;
                }
                if (material.HasProperty(GLTFMatKeys.AI_MATKEY_GLTF_METALLICROUGHNESSAO_TEXTURE, TextureType.Unknown, 0))
                {
                    var t = material.GetProperty(GLTFMatKeys.AI_MATKEY_GLTF_METALLICROUGHNESSAO_TEXTURE,
                                                 TextureType.Unknown, 0);
                    pbr.RoughnessMetallicMap         = LoadTexture(t.GetStringValue());
                    pbr.RoughnessMetallicMapFilePath = t.GetStringValue();
                }
                else if (material.HasTextureSpecular)
                {
                    pbr.RoughnessMetallicMap         = LoadTexture(material.TextureSpecular.FilePath);
                    pbr.RoughnessMetallicMapFilePath = material.TextureSpecular.FilePath;
                }

                if (material.HasTextureDisplacement)
                {
                    pbr.DisplacementMap         = LoadTexture(material.TextureDisplacement.FilePath);
                    pbr.DisplacementMapFilePath = material.TextureDisplacement.FilePath;
                }
                if (material.HasTextureLightMap)
                {
                    pbr.AmbientOcculsionMap         = LoadTexture(material.TextureLightMap.FilePath);
                    pbr.AmbientOcculsionMapFilePath = material.TextureLightMap.FilePath;
                }
                if (material.HasTextureEmissive)
                {
                    pbr.EmissiveMap         = LoadTexture(material.TextureEmissive.FilePath);
                    pbr.EmissiveMapFilePath = material.TextureEmissive.FilePath;
                }
                if (material.HasNonTextureProperty(AiMatKeys.UVTRANSFORM_BASE))
                {
                    var values = material.GetNonTextureProperty(AiMatKeys.UVTRANSFORM_BASE).GetFloatArrayValue();
                    if (values != null && values.Length == 5)
                    {
                        pbr.UVTransform = new UVTransform(values[0], new Vector2(values[1], values[2]), new Vector2(values[3], values[4]));
                    }
                }
                return(pbr);
            }