みなさん、こんにちは。私の名前はグリゴリー・ディアディチェンコです。私はUnityの開発に約7年間携わっており、その間に多くのことを見てきました。経験の浅い人からプロジェクトを奪うときに発生する主な問題の1つは、インターフェイスの勾配です。一般的に、インターフェース設計の間違いは珍しいことではありません。ナインスライス、アトラス、バッチ処理の理解を使用できないのと同じように思えます。ただし、グラデーションは、ビルドの重みを想像を絶するサイズに膨らませるか、奇妙な圧縮アーティファクトのあるインターフェイスに描画されるため、少し目立ちます。解決策として、なぜこれが起こっているのか、そしてそれに対して何ができるのかを議論しましょう。このトピックに興味がある人-猫の下で歓迎します。
? ( ), . , , , .
. , , . 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 — , “” . , .
, .
. , — 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 . , .
, !