ImageVerifierCode 换一换
格式:DOCX , 页数:10 ,大小:351.68KB ,
资源ID:28803021      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/28803021.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(一种UGUI的Outline描边优化方案.docx)为本站会员(b****8)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

一种UGUI的Outline描边优化方案.docx

1、一种UGUI的Outline描边优化方案一种UGUI的Outline描边优化方案1.起因我们最近的项目使用了UGUI作为UI系统,在使用UGUI的过程中遇到了不少问题,其中一个问题是:描边的文字与美术同学出的效果图有不小的差异。效果图的描边效果连贯而且均匀,而UGUI的Outline组件的效果仅仅只是解决了“温饱问题”,Better Than Not而已,并且这种实现方式带来了其他问题,比如顶点数量的大幅增加。图1.美术同学的效果图与实际实现的对比(放大至300%)2.原因分析 UGUI已经部分开源,通过研究Outline的源码可以看到,Outline组件的原理是在原顶点的基础上,在effec

2、tDistance.(x,y), (x, -y), (-x,y), (-x,-y)这4个偏移上ApplyShadowZeroAlloc实现的。亦即Outline组件是在Shadow的基础上实现的,Outline相当于4个不同偏移方向上的Shadow。图2. UGUI Outline组件的核心源码进一步查看Shadow的源码,发现Shadow的原理实际上是将原始的顶点数据复制一份,根据设置的偏移量计算复制后的新顶点的位置,并为新的顶点颜色赋值为设置的颜色值。图3. Shadow组件的核心源码顺便吐槽一下Shadow组件的ApplyShadow方法和ApplyShadowZeroAlloc方法,恕

3、我愚钝没有看出这样设计的好处。推测可能是为了跟老版本兼容。我们可以简单地将Outline的参数EffectDistance调整到一个较大的值即可观察到4次复制。实际上Outline在处理1像素以上的描边时就会出现较大瑕疵,超过1.5像素就已经不可用了。图4.Outline偏移参数设置为(10,10)时观察到的4次复制3.业界的一般做法通过请教其他同样使用UGUI的团队以及Google可用的方案,一般有如下几种解决方案:基于Shadow Outline的实现是在原始顶点的4个方向ApplyShadow,为了描边效果更好,可以在8个方向甚至16个方向ApplyShadow来实现饱满的描边效果。实现

4、原理与Outline类似。TextMeshPro看了TextMeshPro官方视频的介绍是令人热血沸腾的,基本解决了策划和美术对UI字体的各种要求。然而TextMeshPro使用时需要制作字体文件,即FontAsset。对于英文及数字来说,只需要针对ASCII字符集制作FontAsset即可,但对于中文需要动态生成的文字来说,需要生成的字体文件相对较大,对于手游项目来说,对包量及内存的影响在目前来看都是不能接受的。但TextMeshPro用在可确定的中文字符及ASCII字符上的效果还是不错的,比如用在登录、主界面这类文字不需要动态生成的界面上。基于Mesh innogames的一位先驱在Blo

5、g上发了一篇通过调整Mesh来对字体描边的思路,奈何2017年4月左右innogames的Blog禁止匿名登录了,通过转载的残缺信息整理实现思路如下: a.提取文字原始UV区域,扩大文字绘图区域 b.对文字纹理的每个像素点周围多次采样,应用描边RGBA作为新的点的颜色 c.将原始纹理及采样后的点进行融合。4.第一次优化采用基于Shadow的实现方式,多次ApplyShadow以使描边效果饱和。 Outline的实现方式是在(x,-y),(x,y),(-x,y),(-x,-y)4个方向ApplyShadow。模仿Outline的实现有了新的BoldOutline,在原有的4个方向之外增加(x,0

6、),(-x,0),(0,y),(0,-y)4个方向共计8个方向的描边。描边效果较Outline有了一定提升。图5.Outline和BoldOutline效果对比当把这样的描边效果应用于场景中人物头顶信息展示时,美术勉强接受了这样的实现效果。然而我却被老大约谈了原因是渲染数据统计窗口(Rendering Statistic Window)中摄像机视野内渲染的顶点总数异常,准确地说是顶点总数爆炸了。理论计算Unity中字符与三角形及顶点数量的关系理应如下表所示:表1.理论计算的各效果数值表从理论上计算,Outline对于1个字符是绘制了5次,BoldOutline是绘制了9次,顶点总数及三角形总数

7、相对于无效果的字符分别应该是5倍和9倍的关系。但是实际运行时却啪啪啪的推翻了这个理论值。表2.实际运行时的各效果数值表图6.各效果运行时的数据截图之所以会出现理论与实际的偏差,就得继续从这些效果实现的原理说起了。在UGUI中Text是由TextGenerator产生顶点数据,通过顶点数据与字体贴图渲染到屏幕上的。Text组件继承自MaskableGraphic,MaskableGraphic又继承自Graphic,Text组件实现了protected virtual void OnPopulateMesh(VertexHelper vh)方法为所需的数据赋值。实现这些文字效果的基础是Unity

8、为外部提供的接口IMeshModifier,如果Text组件所在的GameObject中存在实现了IMeshModifier接口的组件,就会调用对应组件的ModifyMesh方法。这样就可以在外部修改Text的顶点数据了。图7.典型的顶点修改组件结构了解了各种文字效果实现的原理,继续来看关键函数ModifyMesh(VertexHelper vh)的具体实现。Text组件生成的顶点数据通过参数类型VertexHelper传入后,需要通过public voidGetUIVertexStream(Liststream)这个方法获取具体数据。Verts/Tris比值的变化就发生在这个帮助函数中。这个

9、函数将原本共享的三角形顶点做了拆分,按照1个三角形对应3个顶点的数据输出了。引用一位国外Unity开发者的话讲: GetUIVertexStream takes a nice optimized mesh with shared verts and completely ruins it. Dont call it. Ever.Unity这样实现的出发点不得而知,在我们这种应用场景中进一步导致了顶点数的增长。我们是一个MMORPG手游项目,部分副本及城战玩法需要支持大量玩家及怪物同屏。抛开遮挡裁剪这部分优化不谈因为那是另一个优化方向了就描边效果来说,一个字符对应54个顶点,一段简短的200字的

10、文字轻轻松松顶点数破10K。如果说应用于位置固定的UI面板上还勉强可以接受的话,那么应用于相对位置时刻都在发生变更的人物头顶信息上就是不可接受的了。事实上,如果同一个Canvas下的顶点数过多,Unity会报错的。Canvas element contains more than 65535 vertices. This is not supported。图8.顶点数超限Unity报错5.第二次优化简单的基于Shadow的实现方式会引起顶点数量的暴涨,第二次优化将方向调整为了基于Mesh。实现思路如下:(1)在字符原UV边界uvOrigin的基础上,通过描边大小fSize计算描边后的UV边界u

11、vAdd.(2)将原UV边界uvOrigin,扩展后的UV边界uvAdd,描边大小fSize以及描边颜色color传入Shader.将顶点信息传入Shader时需要注意,UIVertex结构体的成员如下:图9.UIVertex结构体没有被默认Shader使用的参数是uv1,normal及tangent。这些需要传给Shader的值就塞进这些参数里就可以了,在Shader中只要逆向解出一一对应即可。(3)对字符贴图像素处理时,从当前像素向四周做8次采样以确定当前像素点的值。采样时需要判断当前点是否是在uvOrigin的范围内,否则的话可能会出现采样到隔壁字符的情况判断当前点是否在uvOrigin

12、的方法如下,在范围内返回1,不在范围内返回0.图10.使用Step方法判断范围沿当前像素采样的8个方向偏移,数组已经被解开,避免需要在Shader中用循环来实现。图11.采样偏移矩阵将所有采样点采样的像素值求和,然后除以采样的数量。图12.对(-1,-1)偏移采样(4)在接下来的pass中将字符的原始贴图信息与刚刚计算得到的数据进行融合。需要注意的是,不在uvOrigin中的像素点的color值直接置0.避免uvOrigin之外,uvAdd之内的脏点混进来了。于是我们就得到了这样的结果:图13.描边2像素、15像素效果及对应数据表3. MeshOutline与其他效果对比数据使用MeshOutline后Batches数量为2,而Outline因为是复制的原顶点信息,所以无论复制多少份Batches数量都为1.总的来说,这种优化方式带来的是采样次数的增加及顶点数量的相对减少。

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1