public static String DumpMaterial(Material m)
        {
            var sb = new StringBuilder();

            if (m != null)
            {
                var shader = m.shader;
                sb.AppendFormat("shader: {0}\n", GetAssetGUID(shader));
                sb.AppendLine();

                sb.AppendFormat("enableInstancing: {0}\n", m.enableInstancing);
                sb.AppendFormat("doubleSidedGI: {0}\n", m.doubleSidedGI);
                sb.AppendFormat("globalIlluminationFlags: {0}\n", m.globalIlluminationFlags);
                sb.AppendFormat("renderQueue: {0}\n", m.renderQueue);
                sb.AppendLine();

                sb.AppendFormat("passCount: {0}\n", m.passCount);
                for (int i = 0; i < m.passCount; ++i)
                {
                    var passName = m.GetPassName(i);
                    var enabled  = m.GetShaderPassEnabled(passName);
                    sb.AppendFormat("pass: {0} enabled = {1}\n", passName, enabled);
                }
                sb.AppendLine();

                List <KeyValuePair <String, Texture> > texEnvs = null;
                using (var so = new SerializedObject(m)) {
                    List <KeyValuePair <String, String> > kv = null;
                    var tagMap = so.FindProperty("stringTagMap");
                    if (tagMap != null && tagMap.isArray)
                    {
                        var arraySize = tagMap.arraySize;
                        for (int i = 0; i < arraySize; ++i)
                        {
                            var key   = so.FindProperty(String.Format("stringTagMap.Array.data[{0}].first", i));
                            var value = so.FindProperty(String.Format("stringTagMap.Array.data[{0}].second", i));
                            if (key != null && value != null &&
                                key.propertyType == SerializedPropertyType.String &&
                                value.propertyType == SerializedPropertyType.String)
                            {
                                kv = kv ?? new List <KeyValuePair <String, String> >();
                                kv.Add(new KeyValuePair <String, String>(key.stringValue, value.stringValue));
                            }
                        }
                    }
                    if (kv != null)
                    {
                        kv.Sort((l, r) => l.Key.CompareTo(r.Key));
                        for (int i = 0; i < kv.Count; ++i)
                        {
                            sb.AppendFormat("stringTagMap[{0}]: {1} = {2}\n", i, kv[i].Key, kv[i].Value);
                        }
                    }
                    var envs_array = so.FindProperty("m_SavedProperties.m_TexEnvs.Array");
                    if (envs_array != null && envs_array.isArray)
                    {
                        var arraySize = envs_array.arraySize;
                        for (int i = 0; i < arraySize; ++i)
                        {
                            var envNamePropPath  = String.Format("data[{0}].first", i);
                            var envNameProp      = envs_array.FindPropertyRelative(envNamePropPath);
                            var texValuePropPath = String.Format("data[{0}].second.m_Texture", i);
                            var texValueProp     = envs_array.FindPropertyRelative(texValuePropPath);
                            if (texValueProp != null && envNameProp != null)
                            {
                                var envName = envNameProp.stringValue;
                                if (texValueProp.propertyType == SerializedPropertyType.ObjectReference)
                                {
                                    if (texValueProp.objectReferenceValue != null)
                                    {
                                        texEnvs = texEnvs ?? new List <KeyValuePair <String, Texture> >();
                                        texEnvs.Add(new KeyValuePair <String, Texture>(
                                                        envName, texValueProp.objectReferenceValue as Texture));
                                    }
                                }
                            }
                        }
                    }
                }
                sb.AppendLine();

                if (shader != null)
                {
                    var count = ShaderUtil.GetPropertyCount(shader);
                    for (int i = 0; i < count; ++i)
                    {
                        var name = ShaderUtil.GetPropertyName(shader, i);
                        var type = ShaderUtil.GetPropertyType(shader, i);
                        switch (type)
                        {
                        case ShaderUtil.ShaderPropertyType.Color:
                            sb.AppendFormat("{0} {1} = {2}\n", type, name, m.GetColor(name).ToString());
                            break;

                        case ShaderUtil.ShaderPropertyType.Float:
                        case ShaderUtil.ShaderPropertyType.Range:
                            sb.AppendFormat("{0} {1} = {2}\n", type, name, m.GetFloat(name).ToString());
                            break;

                        case ShaderUtil.ShaderPropertyType.Vector:
                            sb.AppendFormat("{0} {1} = {2}\n", type, name, m.GetVector(name).ToString());
                            break;

                        case ShaderUtil.ShaderPropertyType.TexEnv:
                            var t = m.GetTexture(name);
                            sb.AppendFormat("{0} {1} = {2}\n", ShaderUtil.GetTexDim(shader, i), name, ShaderGUIHelper.GetAssetGUID(t));
                            sb.AppendFormat("float4 {0}_ST, {1}, {2}\n", name, m.GetTextureScale(name), m.GetTextureOffset(name));
                            if (t != null && texEnvs != null)
                            {
                                var _name   = name;
                                var ttIndex = texEnvs.FindIndex(kv => kv.Key == _name);
                                Debug.Assert(ttIndex >= 0 && texEnvs[ttIndex].Value == t);
                            }
                            break;
                        }
                    }
                }
                sb.AppendLine();

                var shaderKeywords = m.shaderKeywords;
                if (shaderKeywords.Length > 0)
                {
                    Array.Sort(shaderKeywords);
                    sb.Append('\n');
                    for (int i = 0; i < shaderKeywords.Length; ++i)
                    {
                        sb.Append(shaderKeywords[i]).Append(";\n");
                    }
                }
                sb.AppendLine();
            }
            return(sb.ToString());
        }