UGUI的Shadow、Outline分析


Shadow

源码关键部分:

/// <summary>
/// Duplicate vertices from start to end and turn them into shadows with the given offset.
/// </summary>
/// <param name="verts">Vert list to copy</param>
/// <param name="color">Shadow color</param>
/// <param name="start">The start index in the verts list</param>
/// <param name="end">The end index in the vers list</param>
/// <param name="x">The shadows x offset</param>
/// <param name="y">The shadows y offset</param>
protected void ApplyShadow(List<UIVertex> verts, Color32 color, int start, int end, float x, float y)
{
    ApplyShadowZeroAlloc(verts, color, start, end, x, y);
}

public override void ModifyMesh(VertexHelper vh)
{
    if (!IsActive())
        return;

    var output = ListPool<UIVertex>.Get();
    vh.GetUIVertexStream(output);

    ApplyShadow(output, effectColor, 0, output.Count, effectDistance.x, effectDistance.y);
    vh.Clear();
    vh.AddUIVertexTriangleStream(output);
    ListPool<UIVertex>.Release(output);
}

ApplyShadowZeroAlloc方法实现

protected void ApplyShadowZeroAlloc(List<UIVertex> verts, Color32 color, int start, int end, float x, float y)
{
    UIVertex vt;

    var neededCapacity = verts.Count + end - start;
    if (verts.Capacity < neededCapacity)
        verts.Capacity = neededCapacity;

    for (int i = start; i < end; ++i)
    {
        vt = verts[i];
        verts.Add(vt);

        Vector3 v = vt.position;
        v.x += x;
        v.y += y;
        vt.position = v;
        var newColor = color;
        if (m_UseGraphicAlpha)
            newColor.a = (byte)((newColor.a * verts[i].color.a) / 255);
        vt.color = newColor;
        verts[i] = vt;
    }
}

阴影的实现原理是将原网格数据复制一份并向指定方向移动指定像素,然后再填充到顶点数据中,所以顶点数和三角面数会增加1倍

Outline

Outline 源码如下:

public class Outline : Shadow
{
    protected Outline()
    {}

    public override void ModifyMesh(VertexHelper vh)
    {
        if (!IsActive())
            return;

        var verts = ListPool<UIVertex>.Get();
        vh.GetUIVertexStream(verts);

        var neededCpacity = verts.Count * 5;
        if (verts.Capacity < neededCpacity)
            verts.Capacity = neededCpacity;

        var start = 0;
        var end = verts.Count;
        ApplyShadowZeroAlloc(verts, effectColor, start, verts.Count, effectDistance.x, effectDistance.y);

        start = end;
        end = verts.Count;
        ApplyShadowZeroAlloc(verts, effectColor, start, verts.Count, effectDistance.x, -effectDistance.y);

        start = end;
        end = verts.Count;
        ApplyShadowZeroAlloc(verts, effectColor, start, verts.Count, -effectDistance.x, effectDistance.y);

        start = end;
        end = verts.Count;
        ApplyShadowZeroAlloc(verts, effectColor, start, verts.Count, -effectDistance.x, -effectDistance.y);

        vh.Clear();
        vh.AddUIVertexTriangleStream(verts);
        ListPool<UIVertex>.Release(verts);
    }
}

调用了4次ApplyShadowZeroAlloc方法,复制了四次顶点数据。是shadow消耗的4倍。

**Shadow通过为图像或者文字的Mesh添加顶点来实现阴影效果,而Outline是在对象四角上各添加了一个Shadow。**由此我们可以得知,Outline的(额外)消耗是Shadow的四倍,所以还是需要谨慎使用。


文章作者: 草莓多多
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 草莓多多 !
  目录