Shadow继承自BaseMeshEffect,BaseMeshEffect会在enable,disable的时候引起顶点脏标记,它实现了接口IMeshModifier,接口存在一个重载函数ModifyMesh,BaseMeshEffect自身的ModifyMesh重写了参数为Mesh的,这个函数会在重建的顶点重构阶段调用,调用参数为VertextHelper的ModifyMesh,这个函数在BaseMeshEffect中是抽象的,Shadow重写它,实际上就是遍历顶点信息,拷贝一份偏移过的顶点信息,值得一提的是它用提前预设list的capacity的方式zeroalloc。Shadow面板有三个属性,effectColor、effectDistance和useGraphicAlpha,修改它们都会引起顶点脏标记
//BaseMeshEffect
public virtual void ModifyMesh(Mesh mesh)
{
using (var vh = new VertexHelper(mesh))
{
ModifyMesh(vh);
vh.FillMesh(mesh);
}
}
public abstract void ModifyMesh(VertexHelper vh);
//Shadow
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);//这个是将ApplyShadowZeroAlloc封装了一层
vh.Clear();
vh.AddUIVertexTriangleStream(output);
ListPool<UIVertex>.Release(output);
}
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;
}
}
Outline继承自Shadow,Shadow是拷贝一份偏移过的顶点信息,而Outline是拷贝四份在上下左右四个方位,以此实现描边效果。因为Shadow和Outline都是以倍数增加的顶点数为代价的,一般用特殊的shader来进行优化。
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);
}
Position As UV1继承自BaseMeshEffect,它是将顶点的position做成Vector2设置给UV1,UV1涉及到光照贴图,没用过,所以仅就了解一下。
public override void ModifyMesh(VertexHelper vh)
{
UIVertex vert = new UIVertex();
for (int i = 0; i < vh.currentVertCount; i++)
{
vh.PopulateUIVertex(ref vert, i);
vert.uv1 = new Vector2(vert.position.x, vert.position.y);
vh.SetUIVertex(vert, i);
}
}