1.UGUI源码阅读之Mask
2.UGUI深入理解--渲染系统
3.使用单色显示屏的源码嵌入式产品有必要上GUI吗?
4.UGUI源码介绍
5.想详细了解unityugui的渲染流程,但是感觉没有专业文献,如
6.UGUI源码导读
UGUI源码阅读之Mask
Mask主要基于模版测试来进行裁剪,因此先来了解一下unity中的源码模版测试。
Unity Shader中的源码模版测试配置代码大致如上
模版测试的伪代码大概如上
传统的渲染管线中,模版测试和深度测试一般发生在片元着色器(Fragment Shader)之后,源码但是源码现在又出现了Early Fragment Test,可以在片元着色器之前进行。源码asp图库源码
Mask直接继承了UIBehaviour类,源码同时继承了ICanvasRaycastFilter和IMaterialModifier接口。源码
Mask主要通过GetModifiedMaterial修改graphic的源码Material。大致流程:
1.获取当前Mask的源码层stencilDepth
2.StencilMaterial.Add修改baseMaterial的模板测试相关配置,并将其缓存
3.StencilMaterial.Add设置一个unmaskMaterial,源码用于最后将模板值还原
MaskableGraphic通过MaskUtilities.GetStencilDepth计算父节点的源码Mask层数,然后StencilMaterial.Add修改模板测试的源码配置。
通过Frame Debugger看看具体每个batch都做了什么。源码先看第一个,源码是Mask1的m_MaskMaterial,关注Stencil相关的数值,白色圆内的stencil buffer的值设置为1
这个是Mask2的m_MaskMaterial,根据stencil的计算公式,Ref & ReadMask=1,Comp=Equal,只有stencil buffer & ReadMask=1的像素可以通过模板测试,即第一个白色圆内的像素,然后Pass=Replace,会将通过的像素写入模板值(Ref & WriteMask=3),即两圆相交部分模板值为3
这个是RawImage的Material,只有模板值等于3的像素可以通过模板测试,所以只有两个圆相交的部分可以写入buffer,其他部分舍弃,通过或者失败都不改变模板值
这是Mask2的unmaskMaterial,将两个圆相交部分的模板值设置为1,也就是还原Mask2之前的stencil buffer
这是Mask1的unmaskMaterial,将第一个圆内的模板值设置为0,还有成最初的stencil buffer
可以看到Mask会产生比较严重的overdraw。
2.drawcall和合批
每添加一个mask,一般会增加2个drawcall(加上mask会阻断mask外和mask内的合批造成的额外drawcall),一个用于设置遮罩用的stencil buffer,一个用于还原stencil buffer。
如图,同一个Mask下放置两个使用相同的RawImage,通过Profiler可以看到两个RawImage可以进行合批
如图,两个RawImage使用相同的,它们处于不同的陌生交友源码Mask之下,但是只要m_StencilValue相等,两个RawImage还是可以进行合批。同时可以看到Mask1和Mask1 (1),Mask2和Mask2 (1)也进行了合批,说明stencilDepth相等的Mask符合合批规则也可以进行合批。
StencilMaterial.Add会将修改后的材质球缓存在m_List中,因此调用StencilMaterial.Add在相同参数情况下将获得同一个材质球。
UGUI深入理解--渲染系统
UGUI展示的机制与渲染系统的关联。显示图像与其他渲染方式一样,需要mesh和material。关键在于如何将这些元素传递给渲染引擎。
UI渲染的流程可划分为三个主要部分。CanvasUpdateRegistry作为驱动系统,负责通知需要更新渲染的UI组件。这种方式避免UI内部数据频繁改变时的重复渲染事件,提升效率,且避免了UI在Update循环中处理逻辑的复杂性。
Graphic作为UI组件的基类,其核心功能是组织mesh和material,并将这些元素传递给CanvasRenderer。CanvasRenderer连接画布与渲染组件,将网格绘制到画布上。尽管其名称可能误导,但实际上它对应于Graphic,而与Canvas直接关联不大。
CanvasRenderer的关键接口包括SetMesh和SetMaterial。这些接口允许在一次设置后,当元素不变时无需重复设置,底层具备缓存机制。同时,mesh与material可以独立设置。
每个Graphic的CanvasRenderer存储当前元素的mesh和material,但并不导致每个Graphic产生单独的drawcall。Canvas通过合批操作整合节点下的Graphic,从而降低性能消耗。合理管理Canvas有助于优化界面渲染性能。
重绘条件包括但不限于:enable、disable、validate操作,SetVerticesDirty、MeshEffect变化、shadow属性调整、littervgl源码分析transform尺寸改变、图像类型、层级、填充方式变化,RawImage的texture与uvRect修改,文本内容变化、Richtex开关等。文本是最频繁触发重绘的元素。
重绘触发机制还包括SetMaterialDirty、image触发动画、显示mask、transform层级变化、canvas层级变化、mask计算等。RawImage替换texture触发动画。同时dirty,包括layout,transform层级变化,Sprite替换、大小调整、图集变化,字体变化等。
遮挡mask有两种实现方式:Rect2DMask和mask。它们仅对子节点生效,适用于特定场景。理论上,可修改源码,但在大多数情况下,这种操作并无必要。
RectMask2D提供矩形区域的遮挡功能,类似于NGUI中的裁剪方式,减少了drawcall,性能较mask更优,但仅限于矩形区域的遮挡。
在实现上,通过CanvasRenderer的EnableRectClipping方法设置遮挡区域,底层设置给_ClipRect。RectMask2D节点下的maskable组件注册到ClipperRegistry,底层控制对应的shader打开宏定义。
Mask通过设置模板缓冲值实现,通过像素测试显示图像,仅在指定区域内显示,番茄影视源码透明度为0的区域不显示。
Mask的实现方式将渲染分为三步:首先渲染mask,设置模板缓冲值;其次渲染模板下的对象,根据模板缓冲值判断是否渲染;最后将模板缓冲区设置为0。
遮挡mask的缺点包括功能限制和可能的性能开销。
与NGUI对比,UGUI通过事件触发重绘,NGUI在每帧Update中检测,复杂界面下可能带来额外消耗。合批在UGUI中表现更优,因底层使用C#,语言层面效率较高。重绘同样是性能消耗点,需注意优化。
在层级管理上,UGUI的节点顺序调整更直观,NGUI需要逐层展开才能查看深度,操作稍显繁琐。在裁剪功能上,UGUI通过Shader实现,NGUI则通过切换Shader和额外创建材质实现,但UGUI的2D裁剪方式更高效,尽管NGUI支持边缘模糊效果,需自定义实现。
图集管理方面,NGUI提供较为灵活的图集控制,而UGUI默认图集管理较为受限,通常需要配合其他方案使用。
综上,UGUI的渲染系统表现良好,遮挡mask功能强大。在图集管理方面,可能需要额外策略以控制包体大小与更新频率,这将使其应用更为灵活和高效。
使用单色显示屏的嵌入式产品有必要上GUI吗?
电子产品的显示技术发展多元化,单色显示屏在诸多嵌入式产品中占据重要角色。然而,面对此类限制,是否需要引入GUI(图形用户界面)作为补充?答案往往基于产品的使用场景、复杂度以及系统资源的考量。
在具体解决方案上,我们可列举出以下几款针对性强、aroon公式源码资源占用低的GUI解决方案,它们分别为SimpleGUI、GUI-lite、MonoGUI以及µGUI。分别从界面设计、硬件要求、功能丰富度及移植便利性几个维度进行了考量。
首先,针对单色显示屏优化,SimpleGUI以其减小资源消耗、提供绘图接口及复杂图形组件著称,旨在用最少元素展现最多内容,兼顾美观性与信息密度,适合单色显示屏产品的GUI需求。此款开源项目可在 gitee.com/Polarix/simpl... 下载获取。
其次,GUI-lite凭借轻量化、快速特性及跨平台支持成为使用者的热门选择。这款开源GUI无需过高硬件配置,且易于移植和使用,开发者可从 gitee.com/idea4good/Gui... 探索其功能。
考虑到中文支持与操作流畅性,MonoGUI提供出色的功能,不仅支持GB标准中包含的2字节汉字显示,还具有中文输入法功能。MonoGUI以C++编写,不依赖第三方源码,移植方便,同时还提供了一系列辅助工具软件。可从 gitee.com/liuxinouc/Mon... 观察其完整设计资料。
最后,µGUI则是一个对几乎全部微控制器系统都适用的免费开源图形库。它不局限于任何显示技术,如LCD、TFT、E-Paper、LED或OLED,使得移植成为可能。这款GUI由ugui.c和ugui.h两个文件组成,提供了窗口、按钮、复选框、文本框、图像等控件支持,并实现触摸操作,是嵌入式系统界面设计的优秀选择,详情可参考 github.com/achimdoebler...
总之,选择是否上GUI,关键在于产品需求、资源限制及用户交互体验的考虑。根据特定产品特点,如需高效显示信息,减少内存占用,提升界面美观与功能交互,以上提到的GUI解决方案均可提供支持,进一步满足不同嵌入式产品的用户界面设计需求。
UGUI源码介绍
本文提供对Unity UI系统(UGUI)源码的概览,内容主要来自官方文档。
UGUI主要由EventSystem和UI两部分构成。
EventSystem部分包含输入模块和射线投射器。输入模块用于配置事件系统的主要逻辑,提供不同平台的开箱即用选项,支持各类输入系统如触控、控制器、键盘和鼠标,并将事件分发至对应组件。射线投射器则用于检测事件位置,决定事件传递至的UI元素。
UI部分结构相对复杂,包含多个类和接口,如IMaterialModifier和IndexedSet等。IMaterialModifier接口允许修改用于渲染的Material,IndexedSet是一种结合List和Dictionary实现的自定义容器,提供快速移除和插入元素的功能,但牺牲了顺序和序列化的友好性。
总之,UGUI源码通过模块化设计和接口定义,为开发者提供了丰富的UI构建和事件处理能力。
想详细了解unityugui的渲染流程,但是感觉没有专业文献,如
理解Unity UI系统的渲染流程,对Unity开发者来说至关重要。本文将详细解析Unity UI (UGUI) 的渲染与事件处理机制,帮助开发者更好地掌握其工作原理。首先,我们来了解整个流程的关键环节。
在游戏运行过程中,UI元素的显示、用户输入的捕获与响应,构成了UGUI的核心功能。这一过程涉及到显示、事件检测、事件调度与事件处理等多个步骤。下图展示了从用户点击事件到系统响应的完整流程。
UGUI通过输入模块如 StandaloneInputModule 或 TouchInputModule 来检测用户输入,并根据事件类型调用相应事件处理逻辑。输入模块对事件的处理逻辑和细节在源码中较为复杂,但关键在于它们能够识别不同类型的事件(如点击、拖动)并通知相应的游戏对象进行响应。
在事件处理过程中,BaseEventData、AxisEventData 和 PointerEventData 是关键的数据类,它们分别记录事件的基本信息,如事件发生的上下文、位置、方向等。当用户执行操作时,这些数据被收集并用于后续的事件处理。
射线碰撞检测是另一重要环节,它帮助系统确定事件应该分配给哪个UI元素进行处理。通过从摄像机屏幕位置发射射线并检测碰撞结果,系统能够精准地将事件传递给目标UI对象,实现交互的无缝衔接。
整个事件处理流程的中枢位于 EventSystem 类中。EventSystem 通过调用输入事件检测模块和射线碰撞检测模块来构建其逻辑框架。EventSystem 类不仅负责事件的调度与执行,还通过 EventInterfaces、EventTrigger 和 EventTriggerType 等类定义事件回调函数,确保正确的UI元素能够响应特定事件。
综上所述,理解UGUI的渲染流程不仅能帮助开发者更高效地构建游戏UI,还能提供宝贵的设计思路。尽管在实际项目中可能无需深入掌握这些底层细节,但对架构的理解对于提升开发效率和解决问题能力至关重要。未来,我们还将探讨具体UI组件的实现细节,例如Button和Image组件,以提供更全面的学习资源。
UGUI源码导读
对于想了解UGUI C#源码阅读顺序的同学,我有些建议。首先,要知道UI组件的渲染需要顶点、材质和Layout数据,这与模型相似但多了Layout。组件脚本继承自MonoBehaviour,当数据改变或组件启用时,会自动加入CanvasUpdateRegistry的更新列表。
源码大致可以分为几个部分:基础组件如Image、Text,它们包含自身数据;CanvasUpdateRegistry负责组件更新,当Canvas更新时会调用组件的方法;辅助工具如LayoutRebuilder、FontData和动画工具CoroutineTween;数据结构工具,如ListPool、ObjectPool等,虽非业务核心,但价值不容忽视;Mask与Mask2D的实现;以及EventSystem的事件处理机制,这部分我已经详细阐述过。
从基础组件开始,Graphic脚本是起点。OnEnable时会调用SetAllDirty,这里包含了组件的三个更新数据:Layout、顶点和材质。SetLayoutDirty等方法负责实际的更新,其中LayoutRebuilder是一个关键的辅助类。当Canvas更新时,会遍历并执行需要更新的LayoutGroup的Rebuild方法。
Image的Filled模式生成Mesh的过程是另一个看点。至于RectMask2D,其工作流程涉及挂载、子物体处理和Canvas重建后的Clip方法。Mask则通过Stencil材质实现子物体的遮罩效果。
最后,推荐关注几个实用的工具脚本,如ObjectPool用于对象管理和CoroutineTween用于动画效果。整体来看,阅读源码时,理解这些结构和流程会让你事半功倍,但需做好心理准备,因为源码可能并不包含详细的DC(详细内容)或Text的文字网格计算等具体实现。
UGUI源码之VertexHelper操作手册
以下内容是对UGUI中VertexHelper操作的总结与解释,旨在清晰地说明其使用方法,但如有理解或解释上的不足,请您指正。
VertexHelper在Unity的UGUI中被引入用于管理UI组件的Mesh网格信息,以避免直接修改Mesh带来的问题。其主要功能是通过顶点流、缓冲区和索引数组三个概念进行网格信息的存储与操作,从而支持UI组件中各种复杂的视觉效果的实现。
网格信息主要包括顶点位置、纹理坐标和法线等属性,以及基于这些顶点所组成的三角形结构。Mesh就是这些顶点和结构的集合,它定义了UI元素的外观。VertexHelper提供了操作这些信息的接口,让开发者能够灵活地调整UI元素的外观和动态效果。
顶点流可以理解为网格顶点的集合,而缓冲区则是包含顶点流与索引数组的数据结构,索引数组则指示了如何将顶点用于构成三角形。将顶点流和索引数组组合起来,便构成了一个完整的Mesh网格。
文本和的网格由于顶点顺序和三角形构成方式的差异,展示出不同的视觉效果。在处理整段文本时,通常会有四个顶点用于构成四个三角形,以达到文字的正确显示。而的网格则仅由四个顶点和两个三角形构成,以确保图像的完整性。
VertexHelper类提供了多种方法来处理网格信息,包括添加三角形、四边形、顶点流与索引数组等,以支持各种UI特效的实现。每种方法都有其特定用途,例如,添加一个四边形需要先添加四个顶点,再指定构成三角形的顺序。
当前VertexHelper中包括几个关键变量,如`currentVertCount`表示顶点流中的当前顶点数量,`currentIndexCount`表示索引数组中的当前索引数量,用于记录网格中已添加元素的进度。
此外,VertexHelper提供了多种公共函数来操作网格信息,这些函数通过灵活地管理顶点流与索引数组,使开发者能够轻松地构建复杂且高质量的UI效果。例如,可以添加和获取在三角形中的顶点流,以冗余的方式存储顶点信息,提高操作效率。
需要注意的是,使用VertexHelper处理网格信息时,要确保顶点流与索引数组中对应的信息完全一致。例如,在添加三角形之前,顶点流中必须包含构成该三角形的三个顶点信息。若不满足这一条件,将无法正确生成网格。
在实际应用中,VertexHelper提供了多种添加和修改网格的方法,支持开发者根据需要创建各种动态的UI效果。例如,通过动态调整顶点位置、法线和纹理坐标,可以实现UI元素的动画、阴影及材质变化等效果。同时,针对顶点流中的单个顶点的操作函数,也使得细节调整变得更为灵活。
VertexHelper在提供丰富功能的同时,对顶点流的数量进行了限制,以避免内存溢出等潜在问题,进一步保障应用的稳定性和效率。最后,提供了一系列针对顶点流的获取与操作方法,让开发者能够以高效方式访问和修改网格数据,从而实现多样化且高质量的UI设计。