Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more..
    Dismiss Notice
  3. Dismiss Notice

Surface Shader does not work on UI? Alternatives?

Discussion in 'Shaders' started by welwordion, Oct 17, 2019.

  1. welwordion

    welwordion

    Joined:
    Jan 14, 2019
    Posts:
    9
    I am trying to color a sliders "workforce" fillbar representing subgroups that make up the total workforce. So I made a surface shader to do this but it does not work correctly with UI elements.
    So what can I change? What Shader type to study etc.
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,238
  3. welwordion

    welwordion

    Joined:
    Jan 14, 2019
    Posts:
    9
    Ok I am getting really embarassed I rewrote the Ui Default shader but for some reason the color does not change at the designed points. I am giving values between 0 and 1 but even if I test this without the loop the results are strange.

    Code (CSharp):
    1.                 uint _SegmentsSize = 0;
    2.                 float _Segments[1000];
    3.                 uint current = 0;
    4.  
    5.                 fixed4 frag(v2f IN) : SV_Target
    6.                 {
    7.                     current = 0;
    8.                     for (int i = 0; i < _SegmentsSize; i++)
    9.                     {
    10.                         if (IN.texcoord.x > _Segments[i]) {
    11.                             current = i+1;
    12.                         }
    13.                     }
    14.  
    15.                    
    16.  
    17.  
    18.                     fixed4 co = fixed4((current) % 3 == 0 ? 1 : 0, (current + 1) % 3 == 0 ? 1 : 0, (current + 2) % 3 == 0 ? 1 : 0, 1);
    19.                     half4 color = (tex2D(_MainTex, IN.texcoord) + _TextureSampleAdd) * IN.color* co;
    20.  
    21.                     #ifdef UNITY_UI_CLIP_RECT
    22.                     color.a *= UnityGet2DClipping(IN.worldPosition.xy, _ClipRect);
    23.                     #endif
    24.  
    25.                     #ifdef UNITY_UI_ALPHACLIP
    26.                     clip(color.a - 0.001);
    27.                     #endif
    28.  
    29.                     return color;
    30.                 }
     
  4. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,238
    First though, I would reduce the size of the array. Assuming you’re not going to need to represent more groups than there are likely to be pixels used by your UI element, set that to something smaller. 16 maybe?

    Then I would pass in an array of colors for each bar, maybe even use the alpha value as the bar % instead of having a separate array. Have each segment value be the full % where the cutoff would be and pre sort the array in c# to be in order of the longest to shortest. Then in the shader test if the current UV.x < that segment, set the color to that segment, iterate over all the segments, and then output the color.
     
  5. welwordion

    welwordion

    Joined:
    Jan 14, 2019
    Posts:
    9
    ^^ well IN.texcoord are the only coordinates I could find.(On the positive side building a new Slider from sprites works good so far)
     
  6. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,238
    UVs == texcoords

    It’s two terms for the same thing. They’re called “UV”s because those are the letters usually used to denote the two components for 2D texture coordinates. Just like position is xyz, texture coordinates are uv (with sometimes a w used for the third component for 3D texture coordinates).

    I would suggest trying to get one slider to work with a material property. You’ll need to use a sprite texture that isn’t part of an atlas, otherwise there’s no way to know what the UV range is.