UGUI内核大探究(十五)Shadow与Outline
2016-09-18 22:27
453 查看
想在Unity3D里为一个图片或者文字添加阴影效果,只需要在该对象上在添加一个Shadow组件。Shadow通过为图像或者文字的Mesh添加顶点来实现阴影效果,而Outline是在对象四角上各添加了一个Shadow。由此我们可以得知,Outline的(额外)消耗是Shadow的四倍,所以还是需要谨慎使用。
按照惯例,附上UGUI源码下载地址。Outline继承自Shadow,Shadow继承自BaseMeshEffect,BaseMeshEffect继承自UIBehaviour和IMeshModifier。
UGUI内核大探究(七)Graphic中提到过,Graphic在生成完Mesh数据之后,会查找对象上IMeshModifier类型的组件,调用它们的ModifyMesh方法,之后再正式生成Mesh。
BaseMeshEffect是一个抽象类,而ModifyMesh是一个抽象方法(以Mesh为参数的ModifyMesh方法是过期的不再讨论),具体在其子类里实现。它的OnEnable、OnDisable(调用时机参见Untiy3D组件小贴士(一)OnEnabled与OnDisabled)和OnDidApplyAnimationProperties(当应用动画属性后),会调用graphic属性的SetVerticesDirty方法(设置顶点数据为脏的,重建图像时重新生成顶点数据)。graphic是一个只读属性,获取的是本对象的Graphic组件(Image、RawImage或Text)。
Shadow的ModifyMesh方法:
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); }获取VertexHelper(暂存顶点数据,用于辅助生成Mesh)里的顶点数据output。然后根据effectColor和effectDistance调整顶点。ApplyShadow会将顶点数乘以2,然后调用ApplyShadowZeroAlloc方法。遍历output的顶点,根据顶点生成一个新的顶点vt,添加到顶点列表里,并将vt的位置加上偏移量,并设置颜色。最后将output重新添加到VertexHelper里面(AddUIVertexTriangleStream会自行生成三角形)。
Outline的ModifyMesh方法:
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); }
Outline将顶点数乘以了5,并在四角上各添加了一组(阴影)顶点。
补充:
除了Shadow和Outline以外,UGUI还内置了一个效果PositionAsUV1。
代码十分简单: public class PositionAsUV1 : BaseMeshEffect
{
protected PositionAsUV1()
{}
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);
}
}
}就是根据坐标点设置uv1坐标(法线贴图坐标),为图片或者文字添加法线贴图效果。
原理我们知道了,那么效果是怎么样的呢?
导入一张贴图:
导入设置Texture Type为Normal map(法线贴图)。
我们新建一个Material,设置shader为UI/Unlit/Detail。将刚刚导入的法线贴图设置为Detail(RGB)。
在场景里新建一个Image,为它设置Material。我们会发现图片的颜色变深了一点,但是除此之外并没有变化。
接着为这个Image对象添加PositionAsUV1组件。如图:
相关文章推荐
- css阴影box-shadow+text-shadow和轮廓outline
- box-shadow实现outline圆角
- 读《CSS.Secrets》,记录下——box-shadow,outline
- UGUI内核大探究(九)Image与RawImage
- UGUI内核大探究(零)
- UGUI内核大探究(十)Layout与Fitter
- 由几道JS笔试题引发的知识点探究十五——JS面向对象编程
- UGUI内核大探究(零)
- UGUI内核大探究(十一)ScrollRect与ScrollBar
- UGUI 文字效果实现(Shadow\Gradient\Outline)
- UGUI内核大探究(四)Selectable与Button
- UGUI text image 等加Shadow OutLine等
- UGUI内核大探究(十八)Raycaster
- css奇技淫巧—box-shadow与outline绘制多重边框效果
- 关于DragShadowBuilder无法显示阴影问题探究
- 探究CSS box-shadow属性
- CSS并不简单--走进border、box-shadow和outline
- UGUI 文字效果实现(Shadow\Gradient\Outline)
- css3中的outline,box-shadow和user-select总结
- Android Outline,Shadow和Clip