Let's talk about gradients in Unity

Hello everyone. My name is Grigory Dyadichenko. I've been in Unity development for about 7 years and have seen a lot during that time. One of the main problems that comes up when you take a project away from inexperienced guys is the gradients in the interfaces. In general, mistakes in interface design are not uncommon. It seems like the same inability to use Nine slice, atlases, understanding of batching. But gradients stand out a bit, as they either inflate the weight of the build to unimaginable sizes, or are drawn in an interface with weird compression artifacts. Let's discuss why this is happening, and what can be done about it, as a solution. Who is interested in this topic - welcome under cat.





? ( ), . , , , .





. , , . Android . , , .



, , . 1 , . .



? , , - . draw call, , , , .





. , , . . , .



, . Image Simple Use Sprite Mesh . Image - Maskable Graphic, Simple quad. Graphic , color vertex. , Image Sprite _MainTex SpriteDefault. , , Image. CanvasRenderer. .



? :







1)

2)







, MaskableGraphic. UI.



. UI [PerRendererData], , . , , , , .



, -, . , Figma. 4 : , , . .





. . , , Unity Gradient, .





public Texture2D GenerateTexture(bool makeNoLongerReadable = false)
{
    Texture2D tex = new Texture2D(1, (int)_GradientResolution, TextureFormat.ARGB32, false, true);
    tex.wrapMode = WrapMode;
    tex.filterMode = FilterMode.Bilinear;
    tex.anisoLevel = 1;
    Color[] colors = new Color[(int)_GradientResolution];
    float div = (float)(int)_GradientResolution;
    for (int i = 0; i < (int)_GradientResolution; ++i)
    {
      float t = (float)i/div;
      colors[i] = _Gradient.Evaluate(t);
    }
    tex.SetPixels(colors);
    tex.Apply(false, makeNoLongerReadable);

    return tex;
}
      
      



filter mode wrap mode . Gradient Resolution — , “” . , .



, .





unity figma gradient - the gradient made by the shader, the rest are textures
unity figma gradient - ,

. , — uv . , uv1 . 





v2f vert (appdata v)
{
  const float PI = 3.14159;
  v2f o;
  o.vertex = UnityObjectToClipPos(v.vertex);
  o.color = v.color;
  o.uv = TRANSFORM_TEX(v.uv, _MainTex);
  o.uv.xy -= 0.5;
  float s = sin (2 * PI * (-v.uv2.x) /360);
  float c = cos (2 * PI * (-v.uv2.x) /360);
  float2x2 rotationMatrix = float2x2( c, -s, s, c);
  rotationMatrix *=0.5;
  rotationMatrix +=0.5;
  rotationMatrix = rotationMatrix * 2-1;
  o.uv.xy = mul (o.uv.xy, rotationMatrix );
  o.uv.xy += 0.5;
  return o;
}
      
      



uv . SampleSpriteTexture - Unity UI.





fixed4 SampleSpriteTexture (float2 uv)
{
	fixed4 color = tex2D (_MainTex, uv);

#if UNITY_TEXTURE_ALPHASPLIT_ALLOWED
	if (_AlphaSplitEnabled)
	color.a = tex2D (_AlphaTex, uv).r;
#endif //UNITY_TEXTURE_ALPHASPLIT_ALLOWED

	return color;
}
fixed4 frag (v2f i) : SV_Target
{
	fixed4 col = SampleSpriteTexture ( i.uv) * i.color;
	return col;
}
      
      



. . .





— . . , , . , . . : , .



, . , , .





v2f vert (appdata v)
{
  v2f o;
  o.vertex = UnityObjectToClipPos(v.vertex);
  o.color = v.color;
  o.uv = TRANSFORM_TEX(v.uv, _MainTex);
  o.center = v.center;
  return o;
}

fixed4 frag (v2f i) : SV_Target
{
  const float PI = 3.14159;
  float x =  (i.uv.x - i.center.x);
  float y =  (i.uv.y - i.center.y);
  float angle = acos(dot(float2(0, 1),normalize(float2(x, y))));
  float sign = (x) / abs(x);
  float TwoPI = PI * 2;
  float2 uv = ( sign*angle - i.center.z / 360 * TwoPI) / TwoPI;
  fixed4 col = SampleSpriteTexture (uv) * i.color; 
  return col;
}
      
      



, uv . up uv uv . , . 5-10 - .





/

. , . , 5 . , . , .





v2f vert (appdata v)
{
  const float PI = 3.14159;
  v2f o;
  o.vertex = UnityObjectToClipPos(v.vertex);
  o.color = v.color;
  o.uv = TRANSFORM_TEX(v.uv, _MainTex);

  float s = sin (2 * PI * (-v.params.z) /360);
  float c = cos (2 * PI * (-v.params.z) /360);
  float2x2 rotationMatrix = float2x2( c, -s, s, c);
  rotationMatrix *=0.5;
  rotationMatrix +=0.5;
  rotationMatrix = rotationMatrix * 2-1;
  o.uv.xy = mul (o.uv.xy - v.center.xy, rotationMatrix );

  o.params = v.params;
  o.center = v.center;
  return o;
}

fixed4 frag (v2f i) : SV_Target
{
	float x =  i.uv.x;
	float y =  i.uv.y;
	float r1 = i.params.x / 2;
	float r2 = i.params.y / 2;
 	float2 uv = sqrt(x * x / r1 + y * y / r2);
	fixed4 col = SampleSpriteTexture (uv) * i.color; 
	return col;
}
      
      



, . .





, . , .





fixed4 frag (v2f i) : SV_Target
{
	float x =  i.uv.x;
	float y =  i.uv.y;
	float r1 = i.params.x / 2;
	float r2 = i.params.y / 2;
	float2 uv = abs(x) / r1 + abs(y) / r2;
	fixed4 col = SampleSpriteTexture (uv) * i.color; 
	return col;
}
      
      



, Figma .





, , . , — , , figma png . , .



, !








All Articles