1.UGUI 源码笔记(一)文件结构和部分组件使用
2.深入理解 Flutter 加载原理 | 京东云技术团队
3.hybridclr源代码解析
4.UGUI深入理解--渲染系统
5.Flutter系统网络加载流程
6.UGUI源码阅读之Mask
UGUI 源码笔记(一)文件结构和部分组件使用
探讨UGUI源码之谜:深度解析文件结构与关键组件
本文将为您揭秘Unity3D UI系统UGUI的源码底层细节。
部分一:源码与实现解析
UGUI是源码基于三维网格系统构建的UI库,源码地址。源码
构建图元时,源码先生成一个方形网格,源码绑定材质球,源码objmtlloader.js源码后者存放要显示的源码图像。性能挑战:材质球和网格渲染过量,源码drawcell时间长。源码
部分二:源码结构探索
以Unity版本.1为例,源码文件结构被清晰地划分。源码
Canvas作为核心组件,源码类比为画布,源码内置了提升效率的源码合并网格功能。
Render Mode描述了Canvas的源码网页源码在线编辑渲染模式;Canvas Scale组件允许您调整Canvas中元素的比例。
UI Scale Mode提供了针对屏幕大小的适应性设置,包括ScreenMatchMode.MatchWidthOrHeight选项。
以设备与游戏屏幕比例为例,计算合适的MatchWidthOrHeight值,通过对数空间转换确保视觉平衡。
部分三:UI元素组件剖析
Image与RawImage组件是展示的基石。
它们之间有显著区别:小尺寸图像适合使用Image,大尺寸则推荐RawImage以提高性能。
当处理大量相似类型但数量较少的时,通常选择RawImage,以减少内存消耗。
部分四:RectTransform:UI元素摆放的秘密
尽管RectTransform属于Unity内部类,但在UGUI中扮演着核心角色,用于定义UI元素的缺少根元素 源码位置、大小与旋转。
锚点Anchors决定子节点的对齐,设置时以父节点的比例计算。
Anchors Presets工具提供了常用的布局选择,连带调整Pivot与位置时更为便捷。
Pivot作为物体自身的支点,影响物体的旋转、缩放与位置调整。
深入理解 Flutter 加载原理 | 京东云技术团队
随着 Flutter 的稳定版本迭代,京东 APP 中的 Flutter 业务日渐增多。Flutter 提供了高效的开发环境、优秀的跨平台适配、丰富功能组件和动画,以及接近原生的相亲整站源码下载交互体验。然而,随之而来的 OOM 问题也逐渐显现,尤其在页面加载大量时。本文将深入探讨 Flutter 中的加载原理,以及使用过程中的注意事项和优化思路。基本使用
使用 Image 控件加载是 Flutter 中的常规操作,其基本方法为:image 参数是 Image 控件中的必选参数,可以是 Asset、网络、文件或内存中的数据源。以网络加载为例,具体使用方式如下:
Image 控件的具体使用方法在官方文档中已有详细说明:[Image widget documentation](/post/UGUI源码阅读之Mask
Mask主要基于模版测试来进行裁剪,因此先来了解一下unity中的模版测试。
Unity Shader中的智客 下载 源码模版测试配置代码大致如上
模版测试的伪代码大概如上
传统的渲染管线中,模版测试和深度测试一般发生在片元着色器(Fragment Shader)之后,但是现在又出现了Early Fragment Test,可以在片元着色器之前进行。
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在相同参数情况下将获得同一个材质球。
SRP合批问题
在项目中,使用SRP进行合批时,发现除了Cull和Keywords外,其他因素也可能导致合批失败。例如,使用不同材质的物体之间位置穿插也会造成合批失败。一个场景中如果有三个Shader,三个物体分别使用这三种Shader,无论它们的穿插顺序如何,理论上只需要三个SRP Batch就能完成渲染,但实际上可能会被拆分成4-6个Batch。这需要开发者找出合适的渲染顺序或使用其他方法解决。
场景中常驻的场景相机和UI相机可能导致动态加载的Prefab自带的渲染相机与之前的渲染结果叠加出现问题,尤其是在移动平台上。尽管Overlay相机可以实现正确的叠加,但Base相机却出现花屏现象。这是因为动态加载的Base相机在设置渲染目标时,colorBuffer的Load Action没有正确调整。目前解决方案是将动态相机设置为Overlay,并通过代码将它放入常驻场景相机的CameraStack中。如果在URP下查看Blit操作时发现问题,可以考虑使用类似RenderTexture.DiscardContents的方法来解决。
关于粒子系统是否支持GPU Instancing,答案是肯定的,但在Unity 版本中,粒子系统必须以Mesh模式使用GPU Instancing。粒子系统的实现与GUI的实现类似,数据放在VBO或UBO上效率提升不大,且限制了通用性。对于URP下场景和UI分辨率分离的需求,可以通过将3D场景渲染到RT中,再将RT作为RawImage的Texture渲染到UI中来实现,或者在URP源码中给每个Camera添加修改RenderScale的组件。