context: /// Credit Brad Nelson (playemgames - bitbucket)
  /// Modified Gradient effect script from http://answers.unity3d.com/questions/1086415/gradient-text-in-unity-522-basevertexeffect-is-obs.html
  /// <summary>
  /// -Uses Unity's Gradient class to define the color
  /// -Offset is now limited to -1,1
  /// -Multiple color blend modes
  /// 
  /// Remember that the colors are applied per-vertex so if you have multiple points on your gradient where the color changes and there aren't enough vertices, you won't see all of the colors.
  /// </summary>
  using System.Collections.Generic;
  
  namespace UnityEngine.UI.Extensions
  {
      [AddComponentMenu("UI/Effects/Extensions/Gradient2")]
  	public class Gradient2 : BaseMeshEffect {
  	 [SerializeField]
  	 Type _gradientType;
  
  	 [SerializeField]
  	 Blend _blendMode = Blend.Multiply;
  
  	 [SerializeField]
  	 [Range(-1, 1)]
  	 float _offset = 0f;
  
  	 [SerializeField]
  	 UnityEngine.Gradient _effectGradient = new UnityEngine.Gradient() { colorKeys = new GradientColorKey[] { new GradientColorKey(Color.black, 0), new GradientColorKey(Color.white, 1) } };
  
  	 #region Properties
  	 public Blend BlendMode {
  		 get { return _blendMode; }
  		 set 
  		 { 
  			 _blendMode = value;
  			 graphic.SetVerticesDirty(); 
  		 }
  	 }
  
  	 public UnityEngine.Gradient EffectGradient {
  		 get { return _effectGradient; }
  		 set 
  		 {
  			  _effectGradient = value;
  			  graphic.SetVerticesDirty(); 
  		 }
  	 }
  
  	 public Type GradientType {
  		 get { return _gradientType; }
  		 set 
  		 { 
  			 _gradientType = value;
  			 graphic.SetVerticesDirty(); 
  		 }
  	 }
  
  	 public float Offset {
  		 get { return _offset; }
  		 set 
  		 { 
  			 _offset = value;
  			 graphic.SetVerticesDirty(); 
  		 }
  	 }
  	 #endregion
  
  	 public override void ModifyMesh(VertexHelper helper) {
  		 if(!IsActive() || helper.currentVertCount == 0)
  			 return;
  
  		 List<UIVertex> _vertexList = new List<UIVertex>();
  
  		 helper.GetUIVertexStream(_vertexList);
  
  		 int nCount = _vertexList.Count;
  		 switch(GradientType) {
  			 case Type.Horizontal: {
  					 float left = _vertexList[0].position.x;
  					 float right = _vertexList[0].position.x;
  					 float x = 0f;
  
  					 for(int i = nCount - 1; i >= 1; --i) {
  						 x = _vertexList[i].position.x;
  
  						 if(x > right) right = x;
  						 else if(x < left) left = x;
  					 }
  
  					 float width = 1f / (right - left);
  					 UIVertex vertex = new UIVertex();
  
  					 for(int i = 0; i < helper.currentVertCount; i++) {
  						 helper.PopulateUIVertex(ref vertex, i);
  
  						 vertex.color = BlendColor(vertex.color, EffectGradient.Evaluate((vertex.position.x - left) * width - Offset));
  
  						 helper.SetUIVertex(vertex, i);
  					 }
  				 }
  				 break;
  
  			 case Type.Vertical: {
  					 float bottom = _vertexList[0].position.y;
  					 float top = _vertexList[0].position.y;
  					 float y = 0f;
  
  					 for(int i = nCount - 1; i >= 1; --i) {
  						 y = _vertexList[i].position.y;
  
  						 if(y > top) top = y;
  						 else if(y < bottom) bottom = y;
  					 }
  
  					 float height = 1f / (top - bottom);
  					 UIVertex vertex = new UIVertex();
  
  					 for(int i = 0; i < helper.currentVertCount; i++) {
  						 helper.PopulateUIVertex(ref vertex, i);
  
  						 vertex.color = BlendColor(vertex.color, EffectGradient.Evaluate((vertex.position.y - bottom) * height - Offset));
  
  						 helper.SetUIVertex(vertex, i);
  					 }
  				 }
  				 break;
  
  			 case Type.Diamond: {
  				
  					float bottom = _vertexList[0].position.y;
  					float top = _vertexList[0].position.y;
  					float y = 0f;
  
  					for(int i = nCount - 1; i >= 1; --i) {
  						y = _vertexList[i].position.y;
  
  						if(y > top) top = y;
  						else if(y < bottom) bottom = y;
  					}
  
  					float height = 1f / (top - bottom);
  
  					helper.Clear();
  					for (int i = 0; i < nCount; i++) helper.AddVert(_vertexList[i]);
  
  					float center = (bottom + top) / 2f;
  					UIVertex centralVertex = new UIVertex();
  					centralVertex.position = (Vector3.right + Vector3.up) * center + Vector3.forward * _vertexList[0].position.z;
  					centralVertex.normal = _vertexList[0].normal;
  					centralVertex.color = Color.white;
  					helper.AddVert(centralVertex);
  
  					for (int i = 1; i < nCount; i++) helper.AddTriangle(i-1,i,nCount);
  					helper.AddTriangle(0,nCount-1,nCount);
  
  					UIVertex vertex = new UIVertex();
  
  					for(int i = 0; i < helper.currentVertCount; i++) {
  						helper.PopulateUIVertex(ref vertex, i);
  
  						vertex.color = BlendColor(vertex.color, EffectGradient.Evaluate(
  							Vector3.Distance(vertex.position, centralVertex.position) * height - Offset));
  						
  						helper.SetUIVertex(vertex, i);
  					}
  				}
  				break;
  
  			case Type.Radial: {
  
  					float left = _vertexList[0].position.x;
  					float right = _vertexList[0].position.x;
  					float bottom = _vertexList[0].position.y;
  					float top = _vertexList[0].position.y;
  
  					float x = 0f;
  					float y = 0f;
  
  					for(int i = nCount - 1; i >= 1; --i) {
  						x = _vertexList[i].position.x;
  
  						if(x > right) right = x;
  						else if(x < left) left = x;
  
  						y = _vertexList[i].position.y;
  
  						if(y > top) top = y;
  						else if(y < bottom) bottom = y;
  					}
  
  					float width = 1f / (right - left);
  					float height = 1f / (top - bottom);
  
  					helper.Clear();
  
  					float centerX = (right + left) / 2f;
  					float centerY = (bottom + top) / 2f;
  					float radiusX = (right - left) / 2f;
  					float radiusY = (top - bottom) / 2f;
  					UIVertex centralVertex = new UIVertex();
  					centralVertex.position = Vector3.right * centerX + Vector3.up * centerY + Vector3.forward * _vertexList[0].position.z;
  					centralVertex.normal = _vertexList[0].normal;
  					centralVertex.color = Color.white;
  
  					int steps = 64;
  					for (int i = 0; i < steps; i++)
  					{
  
gt: 						UIVertex curVertex = new UIVertex();