代码之家  ›  专栏  ›  技术社区  ›  Programmer

使用纹理2d创建平滑的圆角矩形

  •  2
  • Programmer  · 技术社区  · 6 年前

    我正在尝试绘制圆形矩形,它可以用作任何UI组件的纹理。我的目标是用 setpixels32- 函数设置像素,从而创建此圆形纹理。我不想用一个明暗器来完成这个操作。

    这篇文章 post did that but with xna instead of unity.我把它移植到Unity,但是边缘是Jaggy。

    这就是它在统一中的样子:

    以下是移植代码:

    public int width=256;
    公共内部高度=140;
    public int borderthickness=1;//不能为<1
    //边框阴影不能超过边框半径
    public int borderradius=40;//不能为<1
    public int bordershadow=2;
    public list<color32>backgroundcolors=新建列表<color32>();
    public list<color32>bordercolors=新列表<color32>();
    公共浮动首字母HadowIntensity=5f;
    公共浮动最终阴影强度=5F;
    
    
    私有纹理2d resulttex;
    公共场所展示;
    
    空启动()
    {
    背景色。添加(新颜色32(17100255));
    背景色。添加(新颜色32(9,48,173,255));
    
    bordercolors.add(新颜色32(111899255));
    bordercolors.add(新颜色32(1714161255));
    
    resulttex=矩形创建器。
    创建Rounded矩形纹理(宽度、高度、边界厚度,
    borderradius、bordershadow、backgroundcolors、bordercolors、
    首字母HadowIntensity,末字母HadowIntensity);
    
    display.texture=结果tex;
    display.setNativeSize();
    }
    
    
    
    公共类矩形创建者
    {
    公共静态纹理2d创建圆形矩形纹理(int width、int height、int borderthickness、int borderradius、int bordershadow、list<color32>背景色、list<color32>bordercolors、float initialshadowintensity、float finalshadowintensity)
    {
    if(backgroundcolors==null backgroundcolors.count==0)引发新的ArgumentException(“必须至少定义一种背景色(最多四种)。);
    if(bordercolors==null bordercolors.count==0)引发新的argumentexception(“必须至少定义一个边框颜色(最多三个)”);
    if(border radius<1)引发新的argumentexception(“必须定义边界半径(舍入边缘)。”);
    if(borderThickness<1)引发新的argumentException(“必须定义边框厚度”);
    如果(borderthickness+borderradius>height/2 borderthickness+borderradius>width/2),则抛出新的argumentexception(“border太厚和/或太圆,无法适应纹理”);
    if(border shadow>border radius)引发新的argumentexception(“border shadow的大小必须小于border radius(suggeted:shadow<=0.25*radius)”);
    
    纹理2d纹理=新纹理2d(宽度、高度、纹理format.argb32,假);
    color32[]color=new color32[宽度*高度];
    
    对于(int x=0;x<texture.width;x++)
    {
    对于(int y=0;y<texture.height;y++)
    {
    开关(backgroundcolors.count)
    {
    案例4:
    color32 leftcolor0=color32.lerp(背景色[0],背景色[1],((float)y/(width-1));
    color32 rightcolor0=color32.lerp(背景色[2],背景色[3],((float)y/(height-1));
    color[x+width*y]=color32.lerp(leftcolor0,rightcolor0,((float)x/(width-1));
    断裂;
    案例3:
    color32 leftcolor1=color32.lerp(背景色[0],背景色[1],((float)y/(width-1));
    color32 rightcolor1=color32.lerp(背景色[1],背景色[2],((float)y/(height-1));
    color[x+width*y]=color32.lerp(leftcolor1,rightcolor1,((float)x/(width-1));
    断裂;
    案例2:
    color[x+width*y]=color32.lerp(背景色[0],背景色[1],((float)x/(width-1));
    断裂;
    违约:
    颜色[X+宽度*Y]=背景颜色[0];
    断裂;
    }
    
    color[x+width*y]=颜色边框(x,y,width,height,borderthickness,borderradius,bordershadow,color[x+width*y],bordercolors,initialHadowIntensity,finalShadowIntensity);
    }
    }
    
    texture.setpixels32(颜色);
    纹理.apply();
    返回纹理;
    }
    
    private static color32 colorborder(int x,int y,int width,int height,int borderthickness,int borderradius,int bordershadow,color32 initialcolor,list<color32>bordercolors,float initialshadowintensity,float finalshadowintensity)
    {
    rect internalrectangle=新rect((borderthickness+borderradius),(borderthickness+borderradius),width-2*(borderthickness+borderradius),height-2*(borderthickness+borderradius));
    
    
    vector2点=新vector2(x,y);
    if(internalRectangle.contains(point))返回initialColor;
    
    vector2原点=vector2.zero;
    
    if(x<borderThickness+borderRadius)
    {
    如果(y<borderradius+borderthickness)
    原点=新矢量2(borderradius+borderthickness,borderradius+borderthickness);
    否则,如果(Y>高度-(borderradius+borderthickness))
    原点=新矢量2(borderradius+borderthickness,height-(borderradius+borderthickness));
    其他的
    原点=新矢量2(borderradius+borderthickness,y);
    }
    否则,如果(x>宽度-(borderRadius+borderThickness))
    {
    如果(y<borderradius+borderthickness)
    原点=新矢量2(宽度-(borderradius+borderthickness),borderradius+borderthickness);
    否则,如果(Y>高度-(borderradius+borderthickness))
    原点=新矢量2(宽度-(borderradius+borderthickness),高度-(borderradius+borderthickness));
    其他的
    原点=新矢量2(宽度-(borderradius+borderthickness),y);
    }
    其他的
    {
    如果(y<borderradius+borderthickness)
    原点=新矢量2(x,borderradius+borderthickness);
    否则,如果(Y>高度-(borderradius+borderthickness))
    原点=新矢量2(x,高度-(borderradius+borderthickness));
    }
    
    如果(!)原点.equals(vector2.zero)
    {
    浮动距离=矢量2.距离(点、原点);
    
    如果(距离>边框半径+边框厚度+1)
    {
    返回颜色。清除;
    }
    else if(距离>borderradius+1)
    {
    if(bordercolors.count>2)
    {
    float modnum=距离-边界半径;
    
    如果(modnum<borderthickness/2)
    {
    返回color32.lerp(bordercolors[2],bordercolors[1],(float)((modnum)/(borderthickness/2.0));
    }
    其他的
    {
    返回color32.lerp(bordercolors[1],bordercolors[0],(float)((modnum-(borderthickness/2.0))/(borderthickness/2.0));
    }
    }
    
    
    if(bordercolors.count>0)
    返回边框颜色[0];
    }
    else if(距离>borderradius-bordershadow+1)
    {
    float mod=(距离-(borderradius-bordershadow))/bordershadow;
    float shadowdiff=缩写hadowIntensity-finalshadowIntensity;
    返回深色(initialColor,((shadowDiff*mod)+finalshadowIntensity));
    }
    }
    
    返回初始颜色;
    }
    
    专用静态颜色32深色(颜色32颜色,浮动阴影强度)
    {
    返回color32.lerp(color,color.black,shadowIntensity);
    }
    }
    < /代码> 
    
    

    我试图通过更换

    return color32.lerp(color,color.black,shadowIntensity);
    < /代码> 
    
    

    < /P>

    return color32.lerp(color,color.clear,shadowIntensity);
    < /代码> 
    
    

    但这并不能使它光滑透明。它去掉了黑色,但使它更加锯齿状。

    这是它的样子:

    如何平滑纹理边缘?通过设置像素SetPixels32功能。我不想用一个材质球。

    这个post但用XNA代替了Unity。我把它移植到团结但是边缘是锯齿状的.

    这就是它在统一中的样子:

    enter image description here

    以下是移植代码:

    public int width = 256;
    public int height = 140;
    public int borderThickness = 1;  //Cannot be < 1
    //Border shadow cannot be more than Border Radius
    public int borderRadius = 40; //Cannot be < 1
    public int borderShadow = 2;
    public List<Color32> backgroundColors = new List<Color32>();
    public List<Color32> borderColors = new List<Color32>();
    public float initialShadowIntensity = 5f;
    public float finalShadowIntensity = 5f;
    
    
    private Texture2D resultTex;
    public RawImage display;
    
    void Start()
    {
        backgroundColors.Add(new Color32(171, 0, 0, 255));
        backgroundColors.Add(new Color32(9, 48, 173, 255));
    
        borderColors.Add(new Color32(111, 8, 99, 255));
        borderColors.Add(new Color32(171, 4, 161, 255));
    
        resultTex = RectangleCreator.
            CreateRoundedRectangleTexture(width, height, borderThickness,
            borderRadius, borderShadow, backgroundColors, borderColors,
            initialShadowIntensity, finalShadowIntensity);
    
        display.texture = resultTex;
        display.SetNativeSize();
    }
    
    
    
    public class RectangleCreator
    {
        public static Texture2D CreateRoundedRectangleTexture(int width, int height, int borderThickness, int borderRadius, int borderShadow, List<Color32> backgroundColors, List<Color32> borderColors, float initialShadowIntensity, float finalShadowIntensity)
        {
            if (backgroundColors == null || backgroundColors.Count == 0) throw new ArgumentException("Must define at least one background color (up to four).");
            if (borderColors == null || borderColors.Count == 0) throw new ArgumentException("Must define at least one border color (up to three).");
            if (borderRadius < 1) throw new ArgumentException("Must define a border radius (rounds off edges).");
            if (borderThickness < 1) throw new ArgumentException("Must define border thikness.");
            if (borderThickness + borderRadius > height / 2 || borderThickness + borderRadius > width / 2) throw new ArgumentException("Border will be too thick and/or rounded to fit on the texture.");
            if (borderShadow > borderRadius) throw new ArgumentException("Border shadow must be lesser in magnitude than the border radius (suggeted: shadow <= 0.25 * radius).");
    
            Texture2D texture = new Texture2D(width, height, TextureFormat.ARGB32, false);
            Color32[] color = new Color32[width * height];
    
            for (int x = 0; x < texture.width; x++)
            {
                for (int y = 0; y < texture.height; y++)
                {
                    switch (backgroundColors.Count)
                    {
                        case 4:
                            Color32 leftColor0 = Color32.Lerp(backgroundColors[0], backgroundColors[1], ((float)y / (width - 1)));
                            Color32 rightColor0 = Color32.Lerp(backgroundColors[2], backgroundColors[3], ((float)y / (height - 1)));
                            color[x + width * y] = Color32.Lerp(leftColor0, rightColor0, ((float)x / (width - 1)));
                            break;
                        case 3:
                            Color32 leftColor1 = Color32.Lerp(backgroundColors[0], backgroundColors[1], ((float)y / (width - 1)));
                            Color32 rightColor1 = Color32.Lerp(backgroundColors[1], backgroundColors[2], ((float)y / (height - 1)));
                            color[x + width * y] = Color32.Lerp(leftColor1, rightColor1, ((float)x / (width - 1)));
                            break;
                        case 2:
                            color[x + width * y] = Color32.Lerp(backgroundColors[0], backgroundColors[1], ((float)x / (width - 1)));
                            break;
                        default:
                            color[x + width * y] = backgroundColors[0];
                            break;
                    }
    
                    color[x + width * y] = ColorBorder(x, y, width, height, borderThickness, borderRadius, borderShadow, color[x + width * y], borderColors, initialShadowIntensity, finalShadowIntensity);
                }
            }
    
            texture.SetPixels32(color);
            texture.Apply();
            return texture;
        }
    
        private static Color32 ColorBorder(int x, int y, int width, int height, int borderThickness, int borderRadius, int borderShadow, Color32 initialColor, List<Color32> borderColors, float initialShadowIntensity, float finalShadowIntensity)
        {
            Rect internalRectangle = new Rect((borderThickness + borderRadius), (borderThickness + borderRadius), width - 2 * (borderThickness + borderRadius), height - 2 * (borderThickness + borderRadius));
    
    
            Vector2 point = new Vector2(x, y);
            if (internalRectangle.Contains(point)) return initialColor;
    
            Vector2 origin = Vector2.zero;
    
            if (x < borderThickness + borderRadius)
            {
                if (y < borderRadius + borderThickness)
                    origin = new Vector2(borderRadius + borderThickness, borderRadius + borderThickness);
                else if (y > height - (borderRadius + borderThickness))
                    origin = new Vector2(borderRadius + borderThickness, height - (borderRadius + borderThickness));
                else
                    origin = new Vector2(borderRadius + borderThickness, y);
            }
            else if (x > width - (borderRadius + borderThickness))
            {
                if (y < borderRadius + borderThickness)
                    origin = new Vector2(width - (borderRadius + borderThickness), borderRadius + borderThickness);
                else if (y > height - (borderRadius + borderThickness))
                    origin = new Vector2(width - (borderRadius + borderThickness), height - (borderRadius + borderThickness));
                else
                    origin = new Vector2(width - (borderRadius + borderThickness), y);
            }
            else
            {
                if (y < borderRadius + borderThickness)
                    origin = new Vector2(x, borderRadius + borderThickness);
                else if (y > height - (borderRadius + borderThickness))
                    origin = new Vector2(x, height - (borderRadius + borderThickness));
            }
    
            if (!origin.Equals(Vector2.zero))
            {
                float distance = Vector2.Distance(point, origin);
    
                if (distance > borderRadius + borderThickness + 1)
                {
                    return Color.clear;
                }
                else if (distance > borderRadius + 1)
                {
                    if (borderColors.Count > 2)
                    {
                        float modNum = distance - borderRadius;
    
                        if (modNum < borderThickness / 2)
                        {
                            return Color32.Lerp(borderColors[2], borderColors[1], (float)((modNum) / (borderThickness / 2.0)));
                        }
                        else
                        {
                            return Color32.Lerp(borderColors[1], borderColors[0], (float)((modNum - (borderThickness / 2.0)) / (borderThickness / 2.0)));
                        }
                    }
    
    
                    if (borderColors.Count > 0)
                        return borderColors[0];
                }
                else if (distance > borderRadius - borderShadow + 1)
                {
                    float mod = (distance - (borderRadius - borderShadow)) / borderShadow;
                    float shadowDiff = initialShadowIntensity - finalShadowIntensity;
                    return DarkenColor(initialColor, ((shadowDiff * mod) + finalShadowIntensity));
                }
            }
    
            return initialColor;
        }
    
        private static Color32 DarkenColor(Color32 color, float shadowIntensity)
        {
            return Color32.Lerp(color, Color.black, shadowIntensity);
        }
    }
    

    我试图通过更换

    return Color32.Lerp(color, Color.black, shadowIntensity);
    

    具有

    return Color32.Lerp(color, Color.clear, shadowIntensity);
    

    但这并不能使它光滑透明。它去掉了黑色,但使它更加锯齿状。

    这是它的样子:

    enter image description here

    如何平滑纹理边缘?

    1 回复  |  直到 6 年前
        1
  •  2
  •   Programmer    6 年前

    当我把这段代码放在uicanvas的羊皮上时,它看起来很好。这是使用游戏对象获得的默认设置->ui->原始图像

    我刚将组件附加到rawimage,并将display属性设置为自身;

    如果希望Unity执行一些抗锯齿操作,则可以提高原始图像的分辨率并删除对 display.setNativeSize(); 的调用,但随后需要使用其转换组件设置矩形的实际大小。

    使用system.collections; 使用system.collections.generic; 使用单位发动机; 使用UnityEngine.ui; 公共类新行为:单一行为{ 公共int宽度=256; 公共内部高度=140; public int borderthickness=1;//不能为<1 //边框阴影不能超过边框半径 public int borderradius=40;//不能为<1 public int bordershadow=2; public list<color32>backgroundcolors=新建列表<color32>(); public list<color32>bordercolors=新列表<color32>(); 公共浮动首字母HadowIntensity=5f; 公共浮动最终阴影强度=5F; 公共浮动决议乘数=4f; 私有纹理2d resulttex; 公共场所展示; 公共RectTransform RT; 空启动() { 背景色。添加(新颜色32(171、0、0、255)); 背景色。添加(新颜色32(9,48,173,255)); bordercolors.add(新颜色32(111、8、99、255)); bordercolors.add(新颜色32(171、4161255)); resulttex=矩形创建器。 创建Rounded矩形纹理(4,宽度,高度,边界厚度, borderradius、bordershadow、backgroundcolors、bordercolors、 首字母HadowIntensity,末字母HadowIntensity); display.texture=结果tex; rt.sizedelta=新矢量2(宽度、高度); } 公共类矩形创建者 { 公共静态纹理2d创建圆形矩形纹理(int resolutionmultiple,int width,int height,int borderthickness,int borderradius,int bordershadow,list<color32>背景色,list<color32>bordercolors,float initialshadowintensity,float finalshadowintensity) { //if(backgroundcolors==null backgroundcolors.count==0)引发new argumentexception(“必须至少定义一种背景色(最多四种)。); //if(bordercolors==null bordercolors.count==0)引发new argumentexception(“必须至少定义一种边框颜色(最多三种)”); //if(border radius<1)引发新的argumentexception(“必须定义边界半径(舍入边缘)。”); //if(borderthickness<1)引发new argumentexception(“must define border thikness.”); //如果(borderthickness+borderradius>height/2 borderthickness+borderradius>width/2)引发新的argumentexception(“border太厚和/或太圆,无法适应纹理”); //if(border shadow>border radius)throw new argumentexception(“border shadow的大小必须小于border radius(suggeted:shadow<=0.25*radius)”); 宽度=宽度*分辨率倍增器; 高度=高度*分辨率倍增器; 纹理2d纹理=新纹理2d(宽度、高度、纹理format.argb32,假); color32[]color=new color32[宽度*高度]; 对于(int x=0;x<texture.width;x++) { 对于(int y=0;y<texture.height;y++) { 开关(backgroundcolors.count) { 案例4: color32 leftcolor0=color32.lerp(背景色[0],背景色[1],((float)y/(width-1)); color32 rightcolor0=color32.lerp(背景色[2],背景色[3],((float)y/(height-1)); color[x+width*y]=color32.lerp(leftcolor0,rightcolor0,((float)x/(width-1)); 断裂; 案例3: color32 leftcolor1=color32.lerp(背景色[0],背景色[1],((float)y/(width-1)); color32 rightcolor1=color32.lerp(背景色[1],背景色[2],((float)y/(height-1)); color[x+width*y]=color32.lerp(leftcolor1,rightcolor1,((float)x/(width-1)); 断裂; 案例2: color[x+width*y]=color32.lerp(背景色[0],背景色[1],((float)x/(width-1)); 断裂; 违约: 颜色[X+宽度*Y]=背景颜色[0]; 断裂; } color[x+width*y]=颜色边框(x,y,width,height,borderthickness,borderradius,bordershadow,color[x+width*y],bordercolors,initialHadowIntensity,finalShadowIntensity); } } texture.setpixels32(颜色); 纹理.apply(); 返回纹理; } private static color32 colorborder(int x,int y,int width,int height,int borderthickness,int borderradius,int bordershadow,color32 initialcolor,list<color32>bordercolors,float initialshadowintensity,float finalshadowintensity) { rect internalrectangle=新rect((borderthickness+borderradius),(borderthickness+borderradius),width-2*(borderthickness+borderradius),height-2*(borderthickness+borderradius)); vector2点=新vector2(x,y); if(internalRectangle.contains(point))返回initialColor; vector2原点=vector2.zero; if(x<borderThickness+borderRadius) { 如果(y<borderradius+borderthickness) 原点=新矢量2(borderradius+borderthickness,borderradius+borderthickness); 否则,如果(Y>高度-(borderradius+borderthickness)) 原点=新矢量2(borderradius+borderthickness,height-(borderradius+borderthickness)); 其他的 原点=新矢量2(borderradius+borderthickness,y); } 否则,如果(x>宽度-(borderRadius+borderThickness)) { 如果(y<borderradius+borderthickness) 原点=新矢量2(宽度-(borderradius+borderthickness),borderradius+borderthickness); 否则,如果(Y>高度-(borderradius+borderthickness)) 原点=新矢量2(宽度-(borderradius+borderthickness),高度-(borderradius+borderthickness)); 其他的 原点=新矢量2(宽度-(borderradius+borderthickness),y); } 其他的 { 如果(y<borderradius+borderthickness) 原点=新矢量2(x,borderradius+borderthickness); 否则,如果(Y>高度-(borderradius+borderthickness)) 原点=新矢量2(x,高度-(borderradius+borderthickness)); } 如果(!)原点.equals(vector2.zero) { 浮动距离=矢量2.距离(点、原点); 如果(距离>边框半径+边框厚度+1) { 返回颜色。清除; } else if(距离>borderradius+1) { if(bordercolors.count>2) { float modnum=距离-边界半径; 如果(modnum<borderthickness/2) { 返回color32.lerp(bordercolors[2],bordercolors[1],(float)((modnum)/(borderthickness/2.0)); } 其他的 { 返回color32.lerp(bordercolors[1],bordercolors[0],(float)((modnum-(borderthickness/2.0))/(borderthickness/2.0)); } } if(bordercolors.count>0) 返回边框颜色[0]; } else if(距离>borderradius-bordershadow+1) { float mod=(距离-(borderradius-bordershadow))/bordershadow; float shadowdiff=缩写hadowIntensity-finalshadowIntensity; 返回深色(initialColor,((shadowDiff*mod)+finalshadowIntensity)); } } 返回初始颜色; } 私有静态颜色32深色(颜色32颜色,浮动阴影强度) { 返回color32.lerp(color,color.black,shadowIntensity); } } } < /代码>

    编辑:

    在将纹理分辨率宽度、高度增加到大约 2048之后, 624 ,将 borderradius 增加到 300 。最后确保游戏视图上未启用“低分辨率纵横比”。这会导致图像模糊。

    我刚将组件连接到rawimage,并将display属性设置为自身;

    My hierarchy

    My Results

    Zoomed with pixel grid

    如果希望Unity执行一些抗锯齿操作,则可以提高原始图像的分辨率并取消对 display.SetNativeSize(); 但是您需要使用矩形的转换组件来设置矩形的实际大小。

       using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.UI;
    
    public class NewBehaviourScript : MonoBehaviour {
    
    
    public int width = 256;
    public int height = 140;
    public int borderThickness = 1;  //Cannot be < 1
    //Border shadow cannot be more than Border Radius
    public int borderRadius = 40; //Cannot be < 1
    public int borderShadow = 2;
    public List<Color32> backgroundColors = new List<Color32>();
    public List<Color32> borderColors = new List<Color32>();
    public float initialShadowIntensity = 5f;
    public float finalShadowIntensity = 5f;
    
    public float resolutionmultiplier = 4f;
    
    
    private Texture2D resultTex;
    public RawImage display;
    
    public RectTransform rt;
    
    void Start()
    {
        backgroundColors.Add(new Color32(171, 0, 0, 255));
        backgroundColors.Add(new Color32(9, 48, 173, 255));
    
        borderColors.Add(new Color32(111, 8, 99, 255));
        borderColors.Add(new Color32(171, 4, 161, 255));
    
        resultTex = RectangleCreator.
            CreateRoundedRectangleTexture(4, width, height, borderThickness,
            borderRadius, borderShadow, backgroundColors, borderColors,
            initialShadowIntensity, finalShadowIntensity);
    
        display.texture = resultTex;
        rt.sizeDelta = new Vector2(width, height);
    }
    
    
    
    public class RectangleCreator
    {
        public static Texture2D CreateRoundedRectangleTexture(int resolutionmultiplier, int width, int height, int borderThickness, int borderRadius, int borderShadow, List<Color32> backgroundColors, List<Color32> borderColors, float initialShadowIntensity, float finalShadowIntensity)
        {
           // if (backgroundColors == null || backgroundColors.Count == 0) throw new ArgumentException("Must define at least one background color (up to four).");
          //  if (borderColors == null || borderColors.Count == 0) throw new ArgumentException("Must define at least one border color (up to three).");
          //  if (borderRadius < 1) throw new ArgumentException("Must define a border radius (rounds off edges).");
          //  if (borderThickness < 1) throw new ArgumentException("Must define border thikness.");
         //   if (borderThickness + borderRadius > height / 2 || borderThickness + borderRadius > width / 2) throw new ArgumentException("Border will be too thick and/or rounded to fit on the texture.");
         //   if (borderShadow > borderRadius) throw new ArgumentException("Border shadow must be lesser in magnitude than the border radius (suggeted: shadow <= 0.25 * radius).");
    
            width = width * resolutionmultiplier;
            height = height * resolutionmultiplier;
    
            Texture2D texture = new Texture2D(width, height, TextureFormat.ARGB32, false);
            Color32[] color = new Color32[width * height];
    
            for (int x = 0; x < texture.width; x++)
            {
                for (int y = 0; y < texture.height; y++)
                {
                    switch (backgroundColors.Count)
                    {
                        case 4:
                            Color32 leftColor0 = Color32.Lerp(backgroundColors[0], backgroundColors[1], ((float)y / (width - 1)));
                            Color32 rightColor0 = Color32.Lerp(backgroundColors[2], backgroundColors[3], ((float)y / (height - 1)));
                            color[x + width * y] = Color32.Lerp(leftColor0, rightColor0, ((float)x / (width - 1)));
                            break;
                        case 3:
                            Color32 leftColor1 = Color32.Lerp(backgroundColors[0], backgroundColors[1], ((float)y / (width - 1)));
                            Color32 rightColor1 = Color32.Lerp(backgroundColors[1], backgroundColors[2], ((float)y / (height - 1)));
                            color[x + width * y] = Color32.Lerp(leftColor1, rightColor1, ((float)x / (width - 1)));
                            break;
                        case 2:
                            color[x + width * y] = Color32.Lerp(backgroundColors[0], backgroundColors[1], ((float)x / (width - 1)));
                            break;
                        default:
                            color[x + width * y] = backgroundColors[0];
                            break;
                    }
    
                    color[x + width * y] = ColorBorder(x, y, width, height, borderThickness, borderRadius, borderShadow, color[x + width * y], borderColors, initialShadowIntensity, finalShadowIntensity);
                }
            }
    
            texture.SetPixels32(color);
            texture.Apply();
            return texture;
        }
    
        private static Color32 ColorBorder(int x, int y, int width, int height, int borderThickness, int borderRadius, int borderShadow, Color32 initialColor, List<Color32> borderColors, float initialShadowIntensity, float finalShadowIntensity)
        {
            Rect internalRectangle = new Rect((borderThickness + borderRadius), (borderThickness + borderRadius), width - 2 * (borderThickness + borderRadius), height - 2 * (borderThickness + borderRadius));
    
    
            Vector2 point = new Vector2(x, y);
            if (internalRectangle.Contains(point)) return initialColor;
    
            Vector2 origin = Vector2.zero;
    
            if (x < borderThickness + borderRadius)
            {
                if (y < borderRadius + borderThickness)
                    origin = new Vector2(borderRadius + borderThickness, borderRadius + borderThickness);
                else if (y > height - (borderRadius + borderThickness))
                    origin = new Vector2(borderRadius + borderThickness, height - (borderRadius + borderThickness));
                else
                    origin = new Vector2(borderRadius + borderThickness, y);
            }
            else if (x > width - (borderRadius + borderThickness))
            {
                if (y < borderRadius + borderThickness)
                    origin = new Vector2(width - (borderRadius + borderThickness), borderRadius + borderThickness);
                else if (y > height - (borderRadius + borderThickness))
                    origin = new Vector2(width - (borderRadius + borderThickness), height - (borderRadius + borderThickness));
                else
                    origin = new Vector2(width - (borderRadius + borderThickness), y);
            }
            else
            {
                if (y < borderRadius + borderThickness)
                    origin = new Vector2(x, borderRadius + borderThickness);
                else if (y > height - (borderRadius + borderThickness))
                    origin = new Vector2(x, height - (borderRadius + borderThickness));
            }
    
            if (!origin.Equals(Vector2.zero))
            {
                float distance = Vector2.Distance(point, origin);
    
                if (distance > borderRadius + borderThickness + 1)
                {
                    return Color.clear;
                }
                else if (distance > borderRadius + 1)
                {
                    if (borderColors.Count > 2)
                    {
                        float modNum = distance - borderRadius;
    
                        if (modNum < borderThickness / 2)
                        {
                            return Color32.Lerp(borderColors[2], borderColors[1], (float)((modNum) / (borderThickness / 2.0)));
                        }
                        else
                        {
                            return Color32.Lerp(borderColors[1], borderColors[0], (float)((modNum - (borderThickness / 2.0)) / (borderThickness / 2.0)));
                        }
                    }
    
    
                    if (borderColors.Count > 0)
                        return borderColors[0];
                }
                else if (distance > borderRadius - borderShadow + 1)
                {
                    float mod = (distance - (borderRadius - borderShadow)) / borderShadow;
                    float shadowDiff = initialShadowIntensity - finalShadowIntensity;
                    return DarkenColor(initialColor, ((shadowDiff * mod) + finalShadowIntensity));
                }
            }
    
            return initialColor;
        }
    
        private static Color32 DarkenColor(Color32 color, float shadowIntensity)
        {
            return Color32.Lerp(color, Color.black, shadowIntensity);
        }
    }
    }
    

    Anti aliased version

    编辑:

    在增加纹理分辨率宽度后,高度大约为 2048 , 624 增加 borderRadius 300 . 最后确保 “低分辨率纵横比” 在游戏视图上未启用。这会导致图像模糊。

    enter image description here