1,所有的UI都是网格绘制的
2,每次绘图之前要准备顶点数据,包含位置,法线,颜色,纹理,坐标,通过一系列操作,交给GPU绘制,绘制的这个过程叫DrallCall
3,beatch批处理,场景中的模型需要做mesh合并,mesh合并可以降低Drallcall
4,Canvas,绘制UI描绘到屏幕上,Canvas下的组件进行批处理,能合并的先合并,然后发送渲染指令到图形系统,获取到子物体的形状描绘出来,通过每个组件中的CanvasRender组件,向画布提供当前物体的几何图形
5,所有能显示的部分都是继承自Graphic类,可以绘制几何图形的类都继承自Graphic,它继承自IcanvasElement(表示图形需要显示到Canvas下的),如果没有canvas不能进行mesh重建
6,脏Dirty标记代表当前的组件被修改过(layout脏标记,材质脏标记,顶点脏标记),如果被修改则需要进行重建,把修改的部分显示出来,需要rebuild,
7,MaskableGraphic继承自Graphic用来图形显示的,遮挡继承自IMaskable接口,能被mask组建剔除
Image继承自MaskableGraphic,也可以被mask组件遮罩
Text也继承自MaskableGraphic
8,LayoutRebuilder类,管理重绘部分,需不需要rebuild进行了注册
会加入到Rebuild队列中,收到rebuild通知的时候重新rebuild
所有能排序的都继承自IlayoutElement接口
通常情况下不建议使用layout进行重建,重建的东西多消耗比较高
9.,CanvasUpdateRegistry,canvas更新的注册
layout的rebuild
Graphic的rebuild
2D遮罩 RectMask2D继承自剪切部分的接口
Mask 主逻辑 模板缓存,
渲染部分
深度测试,测试物体的深度,根据深度绘制物体,颜色缓存区,深度缓存区
透明物体不写深度
UI优化归根揭底到最后都是Canvas的网格重建 rebatch,
网格重建牵扯到两部分,
第1是rebatch,Canvas重新合批造成的消耗,Canvas会把它下面所有的物体合批处理然后进行match的生成,canvas下任何物体发生变化就会重新绘制canvas下的所有物体进行重新合批的操作。
第2是rebuild,针对的是单个物体的重绘,canvas.buildbatch方法会计算当前那些物体需要Rebuild,
上面这个事件会每帧执行
下面的 方法,首先会清除无效的Item(item==nil or item.IsDestory)
下面主要分为三部分,Layoutgroup,屏幕裁剪,Graphic
Layout部分的重建设计到很多计算,如果过度使用,消耗是非常大的,尤其是嵌套的Layout,两三项的情况下,自己去算位置。
Graphic的重建设计到两方面,一个是顶点脏标记,第二个是材质脏标记,只有材质信息发生改变材质脏标记才会改变,修改材质信息不会引发重建
设置顶点脏标记
设置物体或者组件显示,隐藏会把所有的脏标记打开,在关闭和开启的时候进行重绘,控制物体显隐的时候尽量避免使用setactive()
下面的方法会把layout部分,材质部分,全部的顶点设置脏标记,
重建的执行流程
改变颜色,Image调用setcolor()方法,先判断颜色值一样不一样,颜色不一样,才设置顶点的脏标记
设置顶点脏标记,把当前的对象注册进需要重建的Graphic,颜色修改成功后,才会设置顶点的脏标记,
调用注册的方法,把当前的对象注册成为需要重建的graphic
加入到重建队列当中
Canvas每帧都会调用
perform中 执行加进队列中对象的重建
网格重建的部分始终围绕着脏标记,Canvas的合批,或者组件的修改,都是修改了某部分的脏标记,然后进行了重建,
Text每个字都是四个顶点,一个面片,如果Text比较多,控制显隐用Setactive()会重建,面数和顶点数多,展示给用户看又不改变重建没必要的消耗毫无意义,