一种UGUI的Outline描边优化方案
性能消耗原因(例如顶点数量的大幅增加)分析
描边的文字与美术同学出的效果图有不小的差异。效果图的描边效果连贯而且均匀,而UGUI的Outline组件的效果仅仅只是解决了“温饱问题”,Better Than Not而已,并且这种实现方式带来了其他问题,比如顶点数量的大幅增加。
原因分析
通过研究Outline的源码可以看到,Outline组件的原理是在原顶点的基础上,在effectDistance.(x,y), (x, -y), (-x,y), (-x,-y)这4个偏移上ApplyShadowZeroAlloc实现的。亦即Outline组件是在Shadow的基础上实现的,Outline相当于4个不同偏移方向上的Shadow。
进一步查看Shadow的源码,发现Shadow的原理实际上是将原始的顶点数据复制一份, 根据设置的偏移量计算复制后的新顶点的位置,并为新的顶点颜色赋值为设置的颜色值。
我们可以简单地将Outline的参数EffectDistance调整到一个较大的值即可观察到4次复制。实际上Outline在处理1像素以上的描边时就会出现较大瑕疵,超过1.5像素就已经 ...
UGUI的优化方案(2)
DrawCall
CPU每次调用图像编程接口 glDrawElements(OpenGl中的图元渲染函数)或者 DrawIndexedPrimitive(DirectX中的顶点绘制方法)命令GPU渲染的操作称为一次DrawCall。
DrawCall就是一次渲染命令的调用,它指向一个需要被渲染的图元(primitive)列表,不包含任何材质信息,glDrawElements 或者 DrawIndexedPrimitive 函数的作用是将CPU准备好的顶点数据渲染出来。
Batch
把数据加载到显存,设置渲染状态,CPU调用GPU渲染的过程称之为一个Batch。这其实就是渲染流程的运用阶段,最终输出一个渲染图元(点、线、面等),再传递给GPU进行几何阶段和光栅化阶段的渲染显示。一个Batch必然会触发一次或多次DrawCall,且包含了该对象的所有的网格和顶点数据以及材质信息。把数据加载到显存是指把渲染所需的数据从硬盘加载到内存(RAM),再将网格和纹理等加载到显卡(VRAM),这一步比较耗时。设置渲染状态就是设置场景中的网格的顶点(Vertex)/片元(Fragment)着色器,光源 ...
UGUI的优化方案(1)
DrawCall优化方案
在优化UGUI的DrawCall时,我们可以采取以下几种方法:
合并UI元素
将多个相邻的UI元素合并成一个元素,这样可以减少DrawCall的数量。可以使用Unity的Sprite Packer工具来自动合并UI元素
将多个UI元素的纹理合并成一个Atlas,这样可以减少DrawCall的数量。可以使用Unity的Sprite Atlas功能来实现。
使用合批技术
将多个UI元素合并成一个批次,这样可以减少DrawCall的数量。可以使用Unity的Batching功能来实现合批。
静态合批
静态合批是将静态(不移动)GameObjects组合成大网格,然后进行绘制。
静态合批使用比较简单,PlayerSettings中开启static batching,然后对需要静态合批物体的Static打钩即可,unity会自动合并被标记为static的对象,前提它们共享相同的材质,并且不移动,被标记为static的物体不能在游戏中移动,旋转或缩放。
静态批处理需要额外的内存来存储合并的几何体。
注意如果多个GameObject在静态批处理之前共享相同的几何体,则 ...
UGUI渲染机制
浅谈UGUI的渲染机制渲染层级
相机的Layer和Depth:Culling Layer可以决定相机能看到什么Layer,Depth越高的相机,其视野内能看到的所有物体渲染层级越高
Canvas的Layer和Order:
Screen Space - Overlay: UI元素置于屏幕上方,画布自动适应屏幕尺寸改变。Sort Order越大显示越前面
Screen Spacce - Camera: 画布自动适应屏幕尺寸改变,需要设置Render Camera。如果Scene中的GameObject比UI平面更靠近camera,就会遮挡到UI平面。( 其中Order Layer越大显示越前面;Sorting Layer中越在下方的Layer显示越前面 )
World Space: 当UI为场景的一部分,即UI为场景的一部分,需要以3D形式展示。
物体的层级(Hierarchy)关系:如下图, 物体越在Hierarchy窗口里的下方,显示越在前面 (Text > RawImage > Image)
渲染器的对比
UGUI的渲染器是Canvas Render, 同样渲 ...
UGUI运作原理
前言
UGUI的图像显示核心是Graphic类,而Graphic又由Canvas相关类进行管理。在UGUI系统中Canvas管理UI元素的生命周期与样式变化,CanvasRenderer负责UI的显示,包括网格、材质以及Rect裁剪等。由于Canvas与CanvasRenderer真正核心代码未开源,所以只能从Graphic类一探究竟。
UGUI运作原理
UGUI系统的运作核心是CanvasUpdateRegistry类,它通过Canvas的willRenderCanvases回调入手,即每帧在Canvas进行渲染前更新各个Graphic的位置以及渲染信息(mesh、material等),然后根据渲染信息进行渲染,整个运作图如下所示,包括mask在内:
CanvasUpdateRegistry
此类维护了两个队列,即Layout重构队列和Graphic重构队列。这两个队列分别存储了Layout的重构信息(位置、大小)和图像更改信息(mesh、材质等)。在Canvas渲染前通过PerformUpdate进行更新,更新流程如下所示:
移除队列中的非法元素,比如null或者destr ...
三维数学
基础知识
三维数学基础知识
如何判断一个点在三角形(矩形、扇形)内
重心法
面积法
如图:S▲ABP + S▲APC + S▲BPC = S▲ABC
利用叉乘求出各三角形面积即可(叉积的绝对值就是A和B为两边所形成的平行四边形的面积)
叉乘法
首先看一下这个问题,如何判断某两个点在某条直线的同一侧
根据向量的叉乘以及右手螺旋定则,AB x AM 的方向为向外指出屏幕,AB x AN 也是向外指出屏幕,但 AB x AO 的方向是向内指向屏幕,因此 M、N 在直线 AB 的同侧,M、O在直线AB的另一侧。
实际计算时,只需要考虑叉积的数值正负。假设以上各点坐标为A(0,0), B(4,0), M(1,2), N(3,4), O(3,-4), 则:
AB x AM = (4, 0) x (1, 2) = 4 · 2 - 0 · 1 = 8
AB x AN = (4, 0) x (3, 4) = 4 · 4 – 0 · 3 = 16
AB x AO = (4, 0) x (3, -4) = 4 · -4 – 0 · 3 = –16
由上面的数值可知,可以根据数值的正负判断叉乘后 ...