UGUI(2) 减少DrawCall

C#

浏览数:222

2019-8-30

一、动态合批

  1. 要求相同材质,图集
  2. 注意sprite穿插,影响合批。

为什么sprite层级会影响合批?

这关联到渲染顺序。UI元素的默认Render Queue是3000 (UI-Default.shader),即"Queue"="Transparent",半透明对象,没有开启深度写入ZWrite Off,要得到正确的的渲染效果,就必须从后向前渲染(相对于相机)。
若sprite穿插,只能从后向前渲染,无法合批成1次渲染。

UI元素的默认Render Queue.png

UI-Default.shader节选:

SubShader
{
    Tags
    {
        "Queue"="Transparent"
        "IgnoreProjector"="True"
        "RenderType"="Transparent"
        "PreviewType"="Plane"
        "CanUseSpriteAtlas"="True"
    }
    ...
    ZWrite Off
    ZTest [unity_GUIZTestMode]
    ...
}
  1. 注意Mask组件,Mask使用了模板缓冲区,内部子节点不能和外部合批.

Masking is implemented using the stencil buffer of the GPU.

二、空Sprite响应点击,替代透明Image,无DrawCall方案

使用透明Image作为响应点击的Graphic会增加一个DrawCall,如何实现一个无DrawCall方案呢?

关键有2点:

  1. 继承Graphic,override OnPopulateMesh方法 toFill.Clear();
  2. 实现ICanvasRaycastFilter,将 Raycast Target置为true,这样才能响应点击。

示例:

public class XXX: Graphic, ICanvasRaycastFilter {

    protected override void Awake() {
        base.Awake();
        color = new Color(1.0f, 1.0f, 1.0f, 0.0f);
    }

    protected override void OnPopulateMesh(VertexHelper toFill) {
        toFill.Clear();
    }

    public virtual bool IsRaycastLocationValid(Vector2 screenPoint, Camera eventCamera) {
        return true;
    }
}

三、圆形或多边形图片,替代Mask,无DrawCall方案

与上面空sprite原理类似,都是对OnPopulateMesh方法的重写

  1. 改写入圆形顶点数据–已知半径;
  2. 设置uv等信息;

丢掉Mask遮罩,更好的圆形Image组件[Unity]

作者:云木unity