private void ExportMaterial(IIGameMaterial materialNode, BabylonScene babylonScene)
        {
            var name = materialNode.MaterialName;
            var id = materialNode.MaxMaterial.GetGuid().ToString();

            RaiseMessage(name, 1);

            if (materialNode.SubMaterialCount > 0)
            {
                var babylonMultimaterial = new BabylonMultiMaterial { name = name, id = id };

                var guids = new List<string>();

                for (var index = 0; index < materialNode.SubMaterialCount; index++)
                {
                    var subMat = materialNode.GetSubMaterial(index);

                    if (subMat != null)
                    {
                        guids.Add(subMat.MaxMaterial.GetGuid().ToString());

                        if (!referencedMaterials.Contains(subMat))
                        {
                            referencedMaterials.Add(subMat);
                            ExportMaterial(subMat, babylonScene);
                        }
                    }
                    else
                    {
                        guids.Add(Guid.Empty.ToString());
                    }
                }

                babylonMultimaterial.materials = guids.ToArray();

                babylonScene.MultiMaterialsList.Add(babylonMultimaterial);
                return;
            }

            var babylonMaterial = new BabylonStandardMaterial
            {
                name = name,
                id = id,
                ambient = materialNode.MaxMaterial.GetAmbient(0, false).ToArray(),
                diffuse = materialNode.MaxMaterial.GetDiffuse(0, false).ToArray(),
                specular = materialNode.MaxMaterial.GetSpecular(0, false).Scale(materialNode.MaxMaterial.GetShinStr(0, false)),
                specularPower = materialNode.MaxMaterial.GetShininess(0, false) * 256,
                emissive =
                    materialNode.MaxMaterial.GetSelfIllumColorOn(0, false)
                        ? materialNode.MaxMaterial.GetSelfIllumColor(0, false).ToArray()
                        : materialNode.MaxMaterial.GetDiffuse(0, false).Scale(materialNode.MaxMaterial.GetSelfIllum(0, false)),
                alpha = 1.0f - materialNode.MaxMaterial.GetXParency(0, false)
            };


            var stdMat = materialNode.MaxMaterial.GetParamBlock(0).Owner as IStdMat2;

            if (stdMat != null)
            {
                babylonMaterial.backFaceCulling = !stdMat.TwoSided;
                babylonMaterial.wireframe = stdMat.Wire;

                // Textures
                BabylonFresnelParameters fresnelParameters;

                babylonMaterial.ambientTexture = ExportTexture(stdMat, 0, out fresnelParameters, babylonScene);                // Ambient
                babylonMaterial.diffuseTexture = ExportTexture(stdMat, 1, out fresnelParameters, babylonScene);                // Diffuse
                if (fresnelParameters != null)
                {
                    babylonMaterial.diffuseFresnelParameters = fresnelParameters;
                }

                babylonMaterial.specularTexture = ExportTexture(stdMat, 2, out fresnelParameters, babylonScene);               // Specular
                babylonMaterial.emissiveTexture = ExportTexture(stdMat, 5, out fresnelParameters, babylonScene);               // Emissive
                if (fresnelParameters != null)
                {
                    babylonMaterial.emissiveFresnelParameters = fresnelParameters;
                    if (babylonMaterial.emissive[0] == 0 &&
                        babylonMaterial.emissive[1] == 0 &&
                        babylonMaterial.emissive[2] == 0 &&
                        babylonMaterial.emissiveTexture == null)
                    {
                        babylonMaterial.emissive = new float[] { 1, 1, 1 };
                    }
                }

                babylonMaterial.opacityTexture = ExportTexture(stdMat, 6, out fresnelParameters, babylonScene, false, true);   // Opacity
                if (fresnelParameters != null)
                {
                    babylonMaterial.opacityFresnelParameters = fresnelParameters;
                    if (babylonMaterial.alpha == 1 &&
                         babylonMaterial.opacityTexture == null)
                    {
                        babylonMaterial.alpha = 0;
                    }
                }

                babylonMaterial.bumpTexture = ExportTexture(stdMat, 8, out fresnelParameters, babylonScene);                   // Bump
                babylonMaterial.reflectionTexture = ExportTexture(stdMat, 9, out fresnelParameters, babylonScene, true);       // Reflection
                if (fresnelParameters != null)
                {
                    if (babylonMaterial.reflectionTexture == null)
                    {
                        RaiseWarning("Fallout cannot be used with reflection channel without a texture", 2);
                    }
                    else
                    {
                        babylonMaterial.reflectionFresnelParameters = fresnelParameters;
                    }
                }

                // Constraints
                if (babylonMaterial.diffuseTexture != null)
                {
                    babylonMaterial.diffuse = new[] { 1.0f, 1.0f, 1.0f };
                }

                if (babylonMaterial.emissiveTexture != null)
                {
                    babylonMaterial.emissive = new float[] { 0, 0, 0 };
                }

                if (babylonMaterial.opacityTexture != null && babylonMaterial.diffuseTexture != null &&
                    babylonMaterial.diffuseTexture.name == babylonMaterial.opacityTexture.name &&
                    babylonMaterial.diffuseTexture.hasAlpha && !babylonMaterial.opacityTexture.getAlphaFromRGB)
                {
                    // This is a alpha testing purpose
                    babylonMaterial.opacityTexture = null;
                    babylonMaterial.diffuseTexture.hasAlpha = true;
                    RaiseWarning("Opacity texture was removed because alpha from diffuse texture can be use instead", 2);
                    RaiseWarning("If you do not want this behavior, just set Alpha Source = None on your diffuse texture", 2);
                }
            }

            babylonScene.MaterialsList.Add(babylonMaterial);
        }
        private BabylonMaterial DumpMaterial(Material material, Renderer renderer)
        {
            var materialNotSupported = false; 

            if (!materialsDictionary.ContainsKey(material.name))
            {
                var bMat = new BabylonStandardMaterial
                {
                    name = material.name,
                    id = Guid.NewGuid().ToString(),
                    diffuse = new float[4],
                    specular = new float[4]
                };

                bMat.diffuse[0] = 1.0f;
                bMat.diffuse[1] = 1.0f;
                bMat.diffuse[2] = 1.0f;
                bMat.diffuse[3] = 1.0f;

                if (material.HasProperty("_Color"))
                {
                    bMat.diffuse = material.color.ToFloat();
                }

                if (material.HasProperty("_SpecColor"))
                {
                    var specColor = material.GetColor("_SpecColor");
                    bMat.specular = specColor.ToFloat();
                }

                if (material.HasProperty("_Shininess"))
                {
                    var specShininess = material.GetFloat("_Shininess");
                    bMat.specularPower = specShininess * 128;
                }

                if (material.HasProperty("_Emission"))
                {
                    var emissiveColor = material.GetColor("_Emission");
                    bMat.emissive = emissiveColor.ToFloat();
                }

                if (material.mainTexture && material.mainTexture.GetType().FullName == "UnityEngine.ProceduralTexture")
                {
                    materialNotSupported = true;
                    Debug.LogWarning("ProceduralTexture: " + material.mainTexture.name + " not supported by Babylon.js");
                }

                if (material.mainTexture && !(materialNotSupported))
                {
                    var mainTexturePath = AssetDatabase.GetAssetPath(material.mainTexture);
                    bMat.diffuseTexture = new BabylonTexture
                    {
                        uScale = material.mainTextureScale.x,
                        vScale = material.mainTextureScale.y,
                        uOffset = material.mainTextureOffset.x,
                        vOffset = material.mainTextureOffset.y
                    };

                    var mainTexture2D = material.mainTexture as Texture2D;

                    CopyTexture(mainTexturePath, mainTexture2D, bMat.diffuseTexture);

                    var alphaCuttOff = 0f;

                    if (material.HasProperty("_Cutoff"))
                    {
                        alphaCuttOff = material.GetFloat("_Cutoff");
                    }

                    if ((mainTexture2D && mainTexture2D.alphaIsTransparency) || alphaCuttOff > 0)
                    {
                        bMat.diffuseTexture.hasAlpha = true;
                        bMat.backFaceCulling = false;
                    }

                    bMat.diffuse[0] = 1.0f;
                    bMat.diffuse[1] = 1.0f;
                    bMat.diffuse[2] = 1.0f;
                    bMat.diffuse[3] = 1.0f;
                }

                bMat.bumpTexture = DumpTextureFromMaterial(material, "_BumpMap");
                bMat.emissiveTexture = DumpTextureFromMaterial(material, "_Illum");
                bMat.ambientTexture = DumpTextureFromMaterial(material, "_LightMap");
                bMat.reflectionTexture = DumpTextureFromMaterial(material, "_Cube");

                if (bMat.ambientTexture == null && renderer.lightmapIndex >= 0 && renderer.lightmapIndex != 255 && LightmapSettings.lightmaps.Length > renderer.lightmapIndex)
                {
                    var lightmap = LightmapSettings.lightmaps[renderer.lightmapIndex].lightmapFar;
                    bMat.lightmapTexture = DumpTexture(lightmap, isLightmap: true);
                    bMat.lightmapTexture.coordinatesIndex = 1;
                    bMat.useLightmapAsShadowmap = true;

                    bMat.lightmapTexture.uScale = renderer.lightmapScaleOffset.x;
                    bMat.lightmapTexture.vScale = renderer.lightmapScaleOffset.y;

                    bMat.lightmapTexture.uOffset = renderer.lightmapScaleOffset.z;
                    bMat.lightmapTexture.vOffset = renderer.lightmapScaleOffset.w;
                }

                materialsDictionary.Add(bMat.name, bMat);
                return bMat;
            }

            return materialsDictionary[material.name];
        }
        private BabylonMaterial DumpStandardMaterial(Material material, int lightmapIndex = -1, Vector4 lightmapScaleOffset = default(Vector4), int lightmapCoordIndex = -1)
        {
            var materialNotSupported = false;
            if (!materialsDictionary.ContainsKey(material.name))
            {
                var bMat = new BabylonStandardMaterial
                {
                    name = material.name,
                    id = Guid.NewGuid().ToString(),
                    diffuse = new float[4],
                    specular = new float[4]
                };

                ExporterWindow.ReportProgress(1, "Exporting standard material: " + material.name);
                if (exportationOptions.DefaultLightmapMode == (int)BabylonLightmapMode.FullLightBaking)
                {
                    bMat.disableLighting = true;
                    bMat.useEmissiveAsIllumination = true;
                }

                // Default diffuse
                bMat.diffuse[0] = 1.0f;
                bMat.diffuse[1] = 1.0f;
                bMat.diffuse[2] = 1.0f;
                bMat.diffuse[3] = 1.0f;

                // Default specular
                bMat.specular[0] = 0.0f;
                bMat.specular[1] = 0.0f;
                bMat.specular[2] = 0.0f;
                bMat.specular[3] = 1.0f;

                if (material.mainTexture && material.mainTexture.GetType().FullName == "UnityEngine.ProceduralTexture")
                {
                    materialNotSupported = true;
                    Debug.LogWarning("ProceduralTexture: " + material.mainTexture.name + " not supported by Babylon.js");
                }

                if (material.HasProperty("_Shininess"))
                {
                    var specShininess = material.GetFloat("_Shininess");
                    bMat.specularPower = specShininess * 128;
                }
                if (material.HasProperty("_Color"))
                {
                    bMat.diffuse = material.color.ToFloat();
                }
                if (material.HasProperty("_SpecColor"))
                {
                    var specColor = material.GetColor("_SpecColor");
                    bMat.specular = specColor.ToFloat();
                }
                if (material.HasProperty("_Emission"))
                {
                    if (material.GetColorNames().IndexOf("_Emission") >= 0)
                    {
                        var emissiveColor = material.GetColor("_Emission");
                        bMat.emissive = emissiveColor.ToFloat();
                    }
                    else if (material.GetFloatNames().IndexOf("_Emission") >= 0)
                    {
                        // TODO: Convert Lightmapper Emission Color
                        UnityEngine.Debug.LogWarning("Material Emission Is Float Not Color: " + material.name);
                    }
                }
                if (material.mainTexture && !materialNotSupported)
                {
                    var mainTexture2D = material.mainTexture as Texture2D;
                    var mainTexturePath = AssetDatabase.GetAssetPath(mainTexture2D);
                    var alphaCuttOff = 0f;
                    if (material.HasProperty("_Cutoff"))
                    {
                        alphaCuttOff = material.GetFloat("_Cutoff");
                    }
                    bMat.diffuseTexture = new BabylonTexture
                    {
                        uScale = material.mainTextureScale.x,
                        vScale = material.mainTextureScale.y,
                        uOffset = material.mainTextureOffset.x,
                        vOffset = material.mainTextureOffset.y
                    };
                    CopyTexture(mainTexturePath, mainTexture2D, bMat.diffuseTexture);
                    if ((mainTexture2D && mainTexture2D.alphaIsTransparency) || alphaCuttOff > 0)
                    {
                        bMat.diffuseTexture.hasAlpha = true;
                        bMat.backFaceCulling = false;
                    }
                }

                // Normal map
                bMat.bumpTexture = DumpTextureFromMaterial(material, "_BumpMap");
                if (bMat.bumpTexture != null && material.HasProperty("_BumpScale"))
                {
                    bMat.bumpTexture.level = material.GetFloat("_BumpScale");
                }

                bMat.emissiveTexture = DumpTextureFromMaterial(material, "_Illum");
                bMat.ambientTexture = DumpTextureFromMaterial(material, "_LightMap");
                bMat.reflectionTexture = DumpTextureFromMaterial(material, "_Cube");

                // If no ambient texture already (ambientTexture manually set for lightmaps on standard material)
                bool hasLightmap = (exportationOptions.ExportLightmaps && lightmapIndex >= 0 && lightmapIndex != 65535 && LightmapSettings.lightmaps.Length > lightmapIndex);
                if (hasLightmap && bMat.ambientTexture == null)
                {
                    var lightmap = LightmapSettings.lightmaps[lightmapIndex].lightmapLight;
                    var texturePath = AssetDatabase.GetAssetPath(lightmap);
                    if (!String.IsNullOrEmpty(texturePath))
                    {
                        ExporterWindow.ReportProgress(1, "Dumping std material lightmap: " + lightmap.name);
                        bMat.lightmapTexture = DumpTexture(lightmap, isLightmap: true);
                        bMat.lightmapTexture.coordinatesIndex = (lightmapCoordIndex >= 0) ? lightmapCoordIndex : exportationOptions.DefaultCoordinatesIndex;
                        bMat.useLightmapAsShadowmap = true;

                        bMat.lightmapTexture.uScale = lightmapScaleOffset.x;
                        bMat.lightmapTexture.vScale = lightmapScaleOffset.y;

                        bMat.lightmapTexture.uOffset = lightmapScaleOffset.z;
                        bMat.lightmapTexture.vOffset = lightmapScaleOffset.w;
                    }
                }
                materialsDictionary.Add(bMat.name, bMat);
                return bMat;
            }
            return materialsDictionary[material.name];
        }