Search Unity

How to: text gradient fill?

Discussion in 'UGUI & TextMesh Pro' started by RyuMaster, Sep 15, 2014.

  1. RyuMaster

    RyuMaster

    Joined:
    Sep 13, 2010
    Posts:
    468
    I want to make similar effect we had in DF GUI, where text color can be gradient. I'm using custom material with build-in UI/Text shader, changing it to something like this:

    half4 frag (v2f i) : COLOR
    {
    half4 col = i.color;
    col.a *= tex2D(_MainTex, i.texcoord).a;
    col = col * _Color * tex2D(_MainTex, i.texcoord);
    clip (col.a - 0.01);
    return col;
    }

    where in "_MainTex" I assign gradient texture.

    I expect color multiply by gradient, but all I get is grey text all the time.
     
    MaxEden likes this.
  2. RyuMaster

    RyuMaster

    Joined:
    Sep 13, 2010
    Posts:
    468
    Solved: There is component UI->Outline, and also community-written UI->Gradient FIll now for the texts;
     
  3. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,775
    Where could one find this?
     
  4. Breyer

    Breyer

    Joined:
    Nov 10, 2012
    Posts:
    412
  5. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,775
    That's beautiful! Thank you.
     
  6. dakka

    dakka

    Joined:
    Jun 25, 2010
    Posts:
    113
    Very nice. Thanks.
     
  7. Stephan-B

    Stephan-B

    Joined:
    Feb 23, 2011
    Posts:
    2,269
    Vertex Color Gradient & Animation
    This video provides a short overview of TextMesh Pro as well as showing the latest implementation of support for Vertex Color Gradients in TextMesh Pro in Unity 4.6 & UI.



    Note that you will be able to animate the (4) vertex colors independently of each other using Unity's Animation component.
     
    Last edited: Sep 19, 2014
    honor0102 likes this.
  8. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,775
  9. Breyer

    Breyer

    Joined:
    Nov 10, 2012
    Posts:
    412
  10. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,775
    I've just realized that I can't animate color values on this Gradient. Do you have any suggestions for that? I suppose I could create a script "bridge" to animate them...
     
  11. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,775
    I created the script bridge to animate the color, but I had to do something else too. The UI apparently doesn't update if it doesn't know it has to, so even if you change the value of the gradient colors by script, you still need to sort of "poke" the UI to make them actually change. I did this by setting the text.color to a random value (since it gets overwritten by the Gradient component anyway).

    I thought I should post this for anyone else who may encounter the same issue.
     
  12. Breyer

    Breyer

    Joined:
    Nov 10, 2012
    Posts:
    412
    I found nice solution but honestly i will create PRO (paid) pack of my extension for few $ mainly aiming on animation support (because most of my extension doesnt support animation or support very dirty)....
     
  13. Stephan-B

    Stephan-B

    Joined:
    Feb 23, 2011
    Posts:
    2,269
    Just to tease a little bit as this is just a first implementation :)


    In this video you can see the Vertex Color Gradient on the text combined with the bevel, soft shadow and the new Animated Overlay FX.


    In this short GIF animation you can see how we are combining vertex color gradient, outline, bevel, soft shadows, overlay FX and bump mapping on the face of the TextMesh Pro text object.


    The font is Impact SDF with some bevel, soft shadow, gradient vertex color and some bump mapping and of course an Animated Overlay EnvMap.
     
    Last edited: Sep 20, 2014
  14. tnbao91

    tnbao91

    Joined:
    Sep 5, 2013
    Posts:
    46
    I have problem when update Unity 5.2.0f3 "BaseVertexEffect Change to BaseMeshEffect"
     
  15. nzgeoff

    nzgeoff

    Joined:
    Jun 27, 2014
    Posts:
    1
  16. LaireonGames

    LaireonGames

    Joined:
    Nov 16, 2013
    Posts:
    705
    I had the same issue, which the new script resolves, however I struggled to get a local vertical gradient (for multi line text elements). To fix I used these lines:


    Code (CSharp):
    1.    case GradientDir.Vertical:
    2.                         if(i % 2 == 0)
    3.                             uiVertex.color *= (i % 3 == 0 || (i - 0) % 3 == 0) ? vertex1 : vertex2;
    4.                         else
    5.                             uiVertex.color *= (i % 3 == 0 || (i - 0) % 3 == 0) ? vertex2 : vertex1;
    6.                         break;
     
  17. AntonQvarfordt

    AntonQvarfordt

    Joined:
    Mar 14, 2013
    Posts:
    27
    "Assets/Script/UI/Effects/Gradient.cs(7,14): error CS0534: `Gradient' does not implement inherited abstract member `UnityEngine.UI.BaseMeshEffect.ModifyMesh(UnityEngine.UI.VertexHelper)'"

    I copied the code from post #15 and get this error. It dosen't seem to register the VertexHelper inside of the function. Or something. Ideas?
     
  18. oddgoo-io

    oddgoo-io

    Joined:
    Aug 22, 2014
    Posts:
    16
    Looking at their source code diff at: https://bitbucket.org/Unity-Technol...fce0998b25b751c99bd&diff2=2f094af18832&at=5.2

    it seems like they added a new abstract method:

    Code (CSharp):
    1.  
    2. public abstract void ModifyMesh(VertexHelper vh);
    3.  
    However, I'm not sure how to implement it since this bit here:

    Code (CSharp):
    1.  
    2. using (VertexHelpervertexHelper2 = newVertexHelper())
    3. {
    4. vertexHelper2.AddUIVertexTriangleStream(list);
    5. vertexHelper2.FillMesh(mesh);
    6. }
    7.  
    is expecting a mesh. Will spend sometime understanding the systems and trying to fix it!
     
  19. Dam-Pete

    Dam-Pete

    Joined:
    Jun 11, 2010
    Posts:
    54
    Code (csharp):
    1.  
    2.     public override void ModifyMesh( VertexHelper vh )
    3.     {
    4.         if( !IsActive() )
    5.             return;
    6.  
    7.         List<UIVertex> list = new List<UIVertex>();
    8.         vh.GetUIVertexStream( list );
    9.  
    10.         ModifyVertices( list );
    11.  
    12.         vh.Clear();
    13.         vh.AddUIVertexTriangleStream( list );
    14.     }
    15.  
    Should work, not sure if it's the best way to implement, but currently works for me in 5.3
     
  20. WarpZone

    WarpZone

    Joined:
    Oct 29, 2007
    Posts:
    326
    Integrated post #19 and added a basic check to account for situations in which the Text's string is "".

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine.UI;
    5. [AddComponentMenu("UI/Effects/Gradient")]
    6. public class Gradient : BaseMeshEffect
    7. {
    8.     public enum Type
    9.     {
    10.         Vertical,
    11.         Horizontal
    12.     }
    13.     [SerializeField]
    14.     public Type GradientType = Type.Vertical;
    15.     [SerializeField]
    16.     [Range(-1.5f, 1.5f)]
    17.     public float Offset = 0f;
    18.     [SerializeField]
    19.     private Color32 StartColor = Color.white;
    20.     [SerializeField]
    21.     private Color32 EndColor = Color.black;
    22.     public override void ModifyMesh( VertexHelper vh )
    23.     {
    24.         if( !IsActive() )
    25.             return;
    26.         List<UIVertex> list = new List<UIVertex>();
    27.         vh.GetUIVertexStream( list );
    28.         ModifyVertices( list );
    29.         vh.Clear();
    30.         vh.AddUIVertexTriangleStream( list );
    31.     }
    32.     public void ModifyVertices(List<UIVertex> _vertexList)
    33.     {
    34.         if (!IsActive())
    35.             return;
    36.         int nCount = _vertexList.Count;
    37.         switch (GradientType)
    38.         {
    39.             case Type.Vertical:
    40.                 {
    41.                     if(_vertexList.Count != 0){
    42.                         float fBottomY = _vertexList[0].position.y;
    43.                         float fTopY = _vertexList[0].position.y;
    44.                         float fYPos = 0f;
    45.    
    46.                         for (int i = nCount - 1; i >= 1; --i)
    47.                         {
    48.                             fYPos = _vertexList[i].position.y;
    49.                             if (fYPos > fTopY)
    50.                                 fTopY = fYPos;
    51.                             else if (fYPos < fBottomY)
    52.                                 fBottomY = fYPos;
    53.                         }
    54.    
    55.                         float fUIElementHeight = 1f / (fTopY - fBottomY);
    56.                         for (int i = nCount - 1; i >= 0; --i)
    57.                         {
    58.                             UIVertex uiVertex = _vertexList[i];
    59.                             uiVertex.color = Color32.Lerp(EndColor, StartColor, (uiVertex.position.y - fBottomY) * fUIElementHeight - Offset);
    60.                             _vertexList[i] = uiVertex;
    61.                         }
    62.                     }
    63.                 }
    64.                 break;
    65.             case Type.Horizontal:
    66.                 {
    67.                     float fLeftX = _vertexList[0].position.x;
    68.                     float fRightX = _vertexList[0].position.x;
    69.                     float fXPos = 0f;
    70.                     for (int i = nCount - 1; i >= 1; --i)
    71.                     {
    72.                         fXPos = _vertexList[i].position.x;
    73.                         if (fXPos > fRightX)
    74.                             fRightX = fXPos;
    75.                         else if (fXPos < fLeftX)
    76.                             fLeftX = fXPos;
    77.                     }
    78.                     float fUIElementWidth = 1f / (fRightX - fLeftX);
    79.                     for (int i = nCount - 1; i >= 0; --i)
    80.                     {
    81.                         UIVertex uiVertex = _vertexList[i];
    82.                         uiVertex.color = Color32.Lerp(StartColor, EndColor, (uiVertex.position.x - fLeftX) * fUIElementWidth - Offset);
    83.                         _vertexList[i] = uiVertex;
    84.                     }
    85.                 }
    86.                 break;
    87.             default: break;
    88.         }
    89.     }
    90. }
     
  21. ThibaultGouala

    ThibaultGouala

    Joined:
    May 30, 2016
    Posts:
    12
    @Stephan_B
    Would it be possible to have this effect based on the mesh rather than on each letters in Text Mesh Pro ?
    The script shared works perfectly fine, it would be great to be able to use Text Mesh Pro amazing possibilities as well.
     
  22. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,595
    When I have time, I can certainly look into this.

    In the meantime, this is something that users should be able to implement as access to the geometry of the text is available.

    See Example 23 - Animating Vertex Attributes and the relate scripts which alters the vertex color of individual characters. As such a similar approach to above could be used to modify the vertex colors to do gradients.