使用SuperTextMesh 针对项目的几个修改记录

相关参考资料
 
项目场景渲染文字,由于Text组件功能太少 选择了SuperTextMesh(STM)
STM 实现原理
通过字体的UV组成几个网格,利用字体图不是透明像素就填充指定颜色,从而保证拉伸后的清晰度
每个字体都是由你当前使用的文字的集合组成一个texture然后每个使用这个字体组件从这个字体的Texutre获取像信息来进行渲染
但是这个Texture动态大小的字体图集,如果使用文字多了,图集就会变大,使用字改变了就会改变贴图的上的文字的UV位置,所有使用这个图集的组件就要更新UV来从新刷新数据
这就需要在Font这个图集刷新的时候刷新下 需要在Font.textureRebuilt添加回调函数
 
修改1 
Font.textureRebuilt 按现在STM的代码。每个STM都会在这个注册个回调,造成这个代理函数队列非常大,总是会卡帧,我改了下STM注册的规则自己注册队列来
把STM源码注册 用这AddFontRebuilt来注册Font.textureRebuilt即可
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
namespace Assets.Clavian.SuperTextMesh.Scripts
{
  
    //字体重绘管理
    //由于Font.textureReBuilt 源码性能问题 如果多个text对象添加到这个队列中,每次回调会有卡顿,所以我这边从新包装下下回调函数
    public class FontUpdate
    {
        public Dictionary<uint, Action<Font>> dic;
        uint indexkey=0;//减少判断key 用个范围增量值来做KEY
        static FontUpdate _instance;
        public static FontUpdate instance
        {
            get
            {
                if (_instance==null)
                {
                    _instance = new FontUpdate();
                }
                return _instance;
            }
        }
        public FontUpdate ()
        {
            dic = new Dictionary<uint, Action<Font>>();
            Font.textureRebuilt += rebuildFont;
        }
        //重绘调用
        void rebuildFont(Font font)
        {
            foreach (Action<Font> item in dic.Values)
            {
                item.Invoke(font);
            }
        }
        //注册一个重绘回调 为了减少寻址导致的消耗,预留uint长度 key 返回一个KEY 作为清理key
        //这个策略有待验证
        public uint AddFontRebuilt(Action<Font> fun )
        {
            indexkey++;
            dic.Add(indexkey,fun);
            return indexkey;
        }
        //清理一个重绘回调
        public void RemoveFontRebuilt(uint index)
        {
            dic.Remove(index);
            if (dic.Count==0)//清理 如果所有都清理  预留key 归零
            {
                indexkey = 0;
                if (sw.util.LoggerHelper.CheckLogLv(sw.util.LogLevel.DEBUG))Debugger.Log("clear RemoveFontRebuilt");
            }
        }
    }
}
 
修改2
最早需求文字是没有背景的,所以场景有N个文字只需要一个drawCall就能完成所有STM的文字渲染
现在有需求需要在文字后面加上背景,这样的话必然会有2个材质叠加渲染,要知道U3D的动态合批是合并上下层级同一个材质的渲染对象。这样就不会动态合批了,性能会有问题。
 
解决办法
STM是用网格去渲染字体,我就在STM源码生成网格上进行修改 生成4个顶点在文字后面 再取一个背景贴图吧贴图渲染上去
1 要保证4个顶点在mesh需要的顶点前4个位置 4个顶点
2 生成2个三角面
3 传入4个UV点保证正向渲染
4 字体的面和会和背景的面重叠 所有 4个顶点位置要Z轴有个0.001的距离,否则会闪烁
5 先生成文字的mesh位置后再计算top left right bootom 4个顶点的位置 
6 shader修改 把渲染文字透明值是0的时候 来填充背景图片
 
UWA上的老兄提示的多材质渲染方式来处理
 
叠加后 自动合批了 哈哈
使用SuperTextMesh 针对项目的几个修改记录