static void SetMaterialKeywords(Material material)
        {
            // Note: keywords must be based on Material value not on MaterialProperty due to multi-edit & material animation
            // (MaterialProperty value might come from renderer material property block)
            bool isSpecularWorkFlow = (WorkflowMode)material.GetFloat("_WorkflowMode") == WorkflowMode.Specular;
            bool hasGlossMap        = false;

            if (isSpecularWorkFlow)
            {
                hasGlossMap = material.GetTexture("_SpecGlossMap");
            }
            else
            {
                hasGlossMap = material.GetTexture("_MetallicGlossMap");
            }

            bool doubleSidedEnable = material.GetFloat(kDoubleSidedEnable) == 1.0f;

            if (doubleSidedEnable)
            {
                DoubleSidedNormalMode doubleSidedNormalMode = (DoubleSidedNormalMode)material.GetFloat(kDoubleSidedNormalMode);
                switch (doubleSidedNormalMode)
                {
                case DoubleSidedNormalMode.Mirror:     // Mirror mode (in tangent space)
                    material.SetVector("_DoubleSidedConstants", new Vector4(1.0f, 1.0f, -1.0f, 0.0f));
                    break;

                case DoubleSidedNormalMode.Flip:     // Flip mode (in tangent space)
                    material.SetVector("_DoubleSidedConstants", new Vector4(-1.0f, -1.0f, -1.0f, 0.0f));
                    break;

                case DoubleSidedNormalMode.None:     // None mode (in tangent space)
                    material.SetVector("_DoubleSidedConstants", new Vector4(1.0f, 1.0f, 1.0f, 0.0f));
                    break;
                }
            }

            //#if defined(_ENABLE_WIND_SINGLE) || defined(_ENABLE_WIND_HIERARCHY) || defined(_ENABLE_WIND_PROCEDURAL)
            VertexAnimationMode vertAnimMode = (VertexAnimationMode)material.GetFloat("_VertexAnimation");

            switch (vertAnimMode)
            {
            case VertexAnimationMode.None:
                CoreUtils.SetKeyword(material, "_ENABLE_WIND_SINGLE", false);
                CoreUtils.SetKeyword(material, "_ENABLE_WIND_HIERARCHY", false);
                CoreUtils.SetKeyword(material, "_ENABLE_WIND_PROCEDURAL", false);
                break;

            case VertexAnimationMode.Hierarchy:
                CoreUtils.SetKeyword(material, "_ENABLE_WIND_SINGLE", false);
                CoreUtils.SetKeyword(material, "_ENABLE_WIND_HIERARCHY", true);
                CoreUtils.SetKeyword(material, "_ENABLE_WIND_PROCEDURAL", false);
                break;

            case VertexAnimationMode.Single:
                CoreUtils.SetKeyword(material, "_ENABLE_WIND_SINGLE", true);
                CoreUtils.SetKeyword(material, "_ENABLE_WIND_HIERARCHY", false);
                CoreUtils.SetKeyword(material, "_ENABLE_WIND_PROCEDURAL", false);
                break;

            case VertexAnimationMode.Procedural:
                CoreUtils.SetKeyword(material, "_ENABLE_WIND_SINGLE", false);
                CoreUtils.SetKeyword(material, "_ENABLE_WIND_HIERARCHY", false);
                CoreUtils.SetKeyword(material, "_ENABLE_WIND_PROCEDURAL", true);
                break;
            }

            CoreUtils.SetKeyword(material, "_DOUBLESIDED_ON", doubleSidedEnable);

            bool isAnisotropic = (BRDFMode)material.GetFloat("_BRDFMode") == BRDFMode.Anisotropic && material.GetTexture("_TangentMap");

            CoreUtils.SetKeyword(material, "_BRDF_ANISO", isAnisotropic);
            CoreUtils.SetKeyword(material, "_BRDF_STANDARD", !isAnisotropic);

            CoreUtils.SetKeyword(material, "_SPECULAR_SETUP", isSpecularWorkFlow);

            CoreUtils.SetKeyword(material, "_METALLICSPECGLOSSMAP", hasGlossMap);
            CoreUtils.SetKeyword(material, "_SPECGLOSSMAP", hasGlossMap && isSpecularWorkFlow);
            CoreUtils.SetKeyword(material, "_METALLICGLOSSMAP", hasGlossMap && !isSpecularWorkFlow);

            CoreUtils.SetKeyword(material, "_NORMALMAP", material.GetTexture("_BumpMap") || material.GetTexture("_DetailNormalMap"));

            CoreUtils.SetKeyword(material, "_SPECULARHIGHLIGHTS_OFF", material.GetFloat("_SpecularHighlights") == 0.0f);
            CoreUtils.SetKeyword(material, "_GLOSSYREFLECTIONS_OFF", material.GetFloat("_GlossyReflections") == 0.0f);

            CoreUtils.SetKeyword(material, "_OCCLUSIONMAP", material.GetTexture("_OcclusionMap"));
            CoreUtils.SetKeyword(material, "_PARALLAXMAP", material.GetTexture("_ParallaxMap"));
            CoreUtils.SetKeyword(material, "_DETAIL_MASK", material.GetTexture("_DetailMask"));
            CoreUtils.SetKeyword(material, "_DETAIL", material.GetTexture("_DetailAlbedoMap") || material.GetTexture("_DetailNormalMap"));
            CoreUtils.SetKeyword(material, "_DETAIL_MULX2", material.GetTexture("_DetailAlbedoMap") || material.GetTexture("_DetailNormalMap"));

            // A material's GI flag internally keeps track of whether emission is enabled at all, it's enabled but has no effect
            // or is enabled and may be modified at runtime. This state depends on the values of the current flag and emissive color.
            // The fixup routine makes sure that the material is in the correct state if/when changes are made to the mode or color.
            MaterialEditor.FixupEmissiveFlag(material);
            bool shouldEmissionBeEnabled = (material.globalIlluminationFlags & MaterialGlobalIlluminationFlags.EmissiveIsBlack) == 0;

            CoreUtils.SetKeyword(material, "_EMISSION", shouldEmissionBeEnabled);

            if (material.HasProperty("_SmoothnessTextureChannel"))
            {
                CoreUtils.SetKeyword(material, "_SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A", GetSmoothnessMapChannel(material) == SmoothnessMapChannel.AlbedoAlpha);
            }
        }
 public void Init(byte[] data)
 {
     //如果要测试mesh模式,就把关于editor的判断去掉
     if (!Application.isEditor && SystemInfo.graphicsDeviceType <= UnityEngine.Rendering.GraphicsDeviceType.OpenGLES2)
     //     if(Application.isEditor)
     {
         //use nesh mode
         _mode = VertexAnimationMode.mesh;
         //use texture mode
         if (data != null)
         {
             MemoryStream memory     = new MemoryStream(data);
             BinaryReader reader     = new BinaryReader(memory);
             int          width      = reader.ReadInt32();
             int          height     = reader.ReadInt32();
             float        animLength = reader.ReadSingle();
             var          realHeight = height >> 1 + 1;
             _vertexFrames = new List <FrameData>(realHeight);
             _meshFrames   = new List <Mesh>(realHeight);
             _tmpList      = new List <Vector3>(width);
             var startJ = 0;
             for (int j = 0; j < height; ++j)
             {
                 bool needAdd = false;
                 if (j % 2 == 0)
                 {
                     needAdd = true;
                     var frameData = new FrameData();
                     _vertexFrames.Add(frameData);
                     _meshFrames.Add(null);
                     frameData.frame = new List <short>(width * 3);
                 }
                 for (int i = 0; i < width; ++i)
                 {
                     var shortX = reader.ReadInt16();
                     var shortY = reader.ReadInt16();
                     var shortZ = reader.ReadInt16();
                     //   var color = new Vector3(shortX / 1000f, shortY / 1000f, shortZ / 1000f);
                     if (needAdd)
                     {
                         _vertexFrames[startJ].frame.Add(shortX);
                         _vertexFrames[startJ].frame.Add(shortY);
                         _vertexFrames[startJ].frame.Add(shortZ);
                     }
                 }
                 if (needAdd)
                 {
                     startJ++;
                 }
             }
             _animationLen = animLength;
             _frameCount   = _vertexFrames.Count;
             _frameTime    = _animationLen / _frameCount;
         }
     }
     else
     {
         _mode = VertexAnimationMode.texture;
         //use texture mode
         if (data != null)
         {
             MemoryStream memory     = new MemoryStream(data);
             BinaryReader reader     = new BinaryReader(memory);
             int          width      = reader.ReadInt32();
             int          height     = reader.ReadInt32();
             float        animLength = reader.ReadSingle();
             var          texture    = new Texture2D(width, height, TextureFormat.RGBAHalf, false);
             for (int j = 0; j < height; ++j)
             {
                 for (int i = 0; i < width; ++i)
                 {
                     var shortX = reader.ReadInt16();
                     var shortY = reader.ReadInt16();
                     var shortZ = reader.ReadInt16();
                     var color  = new Color(shortX / 1000f, shortY / 1000f, shortZ / 1000f, 1f);
                     texture.SetPixel(i, j, color);
                 }
             }
             texture.Apply(false, true);
             _texture      = texture;
             _animationLen = animLength;
         }
     }
 }