예제 #1
0
        private BabylonMaterial DumpShaderMaterial(Material material)
        {
            if (materialsDictionary.ContainsKey(material.name))
            {
                return materialsDictionary[material.name];
            }

            var babylonShaderMaterial = new BabylonShaderMaterial
            {
                name = material.name,
                id = Guid.NewGuid().ToString(),
            };

            ExporterWindow.ReportProgress(1, "Exporting glsl material: " + material.name);

            List<string> tnames = material.GetTextureNames();
            foreach (string tname in tnames)
            {
                BabylonTexture tdata = DumpTextureFromMaterial(material, tname);
                if (tdata != null)
                {
                    babylonShaderMaterial.textures.Add(tname, tdata);
                }
            }

            List<string> fnames = material.GetFloatNames();
            foreach (string fname in fnames)
            {
                float fdata = material.GetFloat(fname);
                babylonShaderMaterial.floats.Add(fname, fdata);
            }

            List<string> rnames = material.GetRangeNames();
            foreach (string rname in rnames)
            {
                float rdata = material.GetFloat(rname);
                babylonShaderMaterial.floats.Add(rname, rdata);
            }

            List<string> cnames = material.GetColorNames();
            foreach (string cname in cnames)
            {
                Color cdata = material.GetColor(cname);
                babylonShaderMaterial.vectors4.Add(cname, cdata.ToFloat());
            }

            List<string> vnames = material.GetVectorNames();
            foreach (string vname in vnames)
            {
                Vector4 vdata = material.GetVector(vname);
                babylonShaderMaterial.vectors4.Add(vname, vdata.ToFloat());
            }

            Shader shader = material.shader;
            string filename = AssetDatabase.GetAssetPath(shader);
            string program = Tools.LoadTextAsset(filename);
            string basename = shader.name.Replace("BabylonJS/", "").Replace("/", "_").Replace(" ", "");
            string outpath = (!String.IsNullOrEmpty(exportationOptions.DefaultShaderFolder)) ? exportationOptions.DefaultShaderFolder : OutputPath;

            var shaderpath = new Dictionary<string, string>();
            List<string> attributeList = new List<string>();
            List<string> uniformList = new List<string>();
            List<string> samplerList = new List<string>();
            List<string> defineList = new List<string>();
            string babylonOptions = GetShaderProgramSection(basename, program, BabylonProgramSection.Babylon);
            string[] babylonLines = babylonOptions.Split('\n');
            foreach (string babylonLine in babylonLines)
            {
                if (babylonLine.IndexOf("attributes", StringComparison.OrdinalIgnoreCase) >= 0)
                {
                    string[] attributes = babylonLine.Split(':');
                    if (attributes != null && attributes.Length > 1)
                    {
                        string abuffer = attributes[1].Replace("[", "").Replace("]", "");
                        if (!String.IsNullOrEmpty(abuffer))
                        {
                            abuffer = abuffer.Trim();
                            string[] adata = abuffer.Split(',');
                            if (adata != null && adata.Length > 0)
                            {
                                foreach (string aoption in adata)
                                {
                                    string aoption_buffer = aoption.Trim().Replace("\"", "").Trim();
                                    if (!String.IsNullOrEmpty(aoption_buffer))
                                    {
                                        attributeList.Add(aoption_buffer);
                                    }
                                }
                            }
                        }
                    }
                }
                else if (babylonLine.IndexOf("uniforms", StringComparison.OrdinalIgnoreCase) >= 0)
                {
                    string[] uniforms = babylonLine.Split(':');
                    if (uniforms != null && uniforms.Length > 1)
                    {
                        string ubuffer = uniforms[1].Replace("[", "").Replace("]", "");
                        if (!String.IsNullOrEmpty(ubuffer))
                        {
                            ubuffer = ubuffer.Trim();
                            string[] udata = ubuffer.Split(',');
                            if (udata != null && udata.Length > 0)
                            {
                                foreach (string uoption in udata)
                                {
                                    string uoption_buffer = uoption.Trim().Replace("\"", "").Trim();
                                    if (!String.IsNullOrEmpty(uoption_buffer))
                                    {
                                        uniformList.Add(uoption_buffer);
                                    }
                                }
                            }
                        }
                    }
                }
                else if (babylonLine.IndexOf("samplers", StringComparison.OrdinalIgnoreCase) >= 0)
                {
                    string[] samplers = babylonLine.Split(':');
                    if (samplers != null && samplers.Length > 1)
                    {
                        string sbuffer = samplers[1].Replace("[", "").Replace("]", "");
                        if (!String.IsNullOrEmpty(sbuffer))
                        {
                            sbuffer = sbuffer.Trim();
                            string[] sdata = sbuffer.Split(',');
                            if (sdata != null && sdata.Length > 0)
                            {
                                foreach (string soption in sdata)
                                {
                                    string soption_buffer = soption.Trim().Replace("\"", "").Trim();
                                    if (!String.IsNullOrEmpty(soption_buffer))
                                    {
                                        samplerList.Add(soption_buffer);
                                    }
                                }
                            }
                        }
                    }
                }
                else if (babylonLine.IndexOf("defines", StringComparison.OrdinalIgnoreCase) >= 0)
                {
                    string[] defines = babylonLine.Split(':');
                    if (defines != null && defines.Length > 1)
                    {
                        string dbuffer = defines[1].Replace("[", "").Replace("]", "");
                        if (!String.IsNullOrEmpty(dbuffer))
                        {
                            dbuffer = dbuffer.Trim();
                            string[] ddata = dbuffer.Split(',');
                            if (ddata != null && ddata.Length > 0)
                            {
                                foreach (string doption in ddata)
                                {
                                    string doption_buffer = doption.Trim().Replace("\"", "").Trim();
                                    if (!String.IsNullOrEmpty(doption_buffer))
                                    {
                                        defineList.Add(doption_buffer);
                                    }
                                }
                            }
                        }
                    }
                }
            }

            babylonShaderMaterial.options = new BabylonShaderOptions();
            babylonShaderMaterial.options.attributes = attributeList.ToArray();
            babylonShaderMaterial.options.uniforms = uniformList.ToArray();
            babylonShaderMaterial.options.samplers = samplerList.ToArray();
            babylonShaderMaterial.options.defines = defineList.ToArray();

            string vertexProgram = GetShaderProgramSection(basename, program, BabylonProgramSection.Vertex);
            var vertextFile = Path.Combine(outpath, basename + ".vertex.fx");
            if (exportationOptions.EmbeddedShaders)
            {
                shaderpath.Add("vertexElement", ("base64:" + Tools.FormatBase64(vertexProgram)));
            }
            else
            {
                File.WriteAllText(vertextFile, vertexProgram);
            }

            string fragmentProgram = GetShaderProgramSection(basename, program, BabylonProgramSection.Fragment);
            var fragmentFile = Path.Combine(outpath, basename + ".fragment.fx");
            if (exportationOptions.EmbeddedShaders)
            {
                shaderpath.Add("fragmentElement", ("base64:" + Tools.FormatBase64(fragmentProgram)));
            }
            else
            {
                File.WriteAllText(fragmentFile, fragmentProgram);
            }

            babylonShaderMaterial.shaderPath = (exportationOptions.EmbeddedShaders) ? (object)shaderpath : (object)basename;
            materialsDictionary.Add(babylonShaderMaterial.name, babylonShaderMaterial);
            return babylonShaderMaterial;
        }
예제 #2
0
        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];
        }