接上回Unity UGUI系列一 Canvas 和 Canvas Group,有个示例,用的图片是SpriteRenderer,而不是UI Image。本文就来总结一下这两者的区别,在这之前,先来看看图片导入。
参考
unity 纹理属性及UI图片导入设置
Unity 图片导入设置
Unity的UI图片规范
一、图片导入后的Texture Type
https://docs.unity.cn/cn/2019.4/Manual/TextureTypes.html
图片的导入类型, 不同的类型适用于不同的应用场景, 也会有不同的设置属性.
- Default 默认. 提供对大多数属性的访问以进行图片导入.
- Normal Map 法线贴图. 此选项可将颜色通道转换为适合实时法线贴图的格式
- Editor GUI and Legacy GUI 编辑器 UI 和传统 UI 类型. 当一张图片要被用来作为编辑器的 UI 或者被 GUI 类所使用的时候, 选择此选项.
- Sprite (2D and UI) 当图片需要作为 2D 游戏中的精灵图时或者被 UGUI 使用时选择此选项.
- Cursor 将图片用作自定义光标时选择此选项
- Cookie 如果图片是作为场景中灯光 Cookie 的参数的时候选择此选项
- Lightmap 将图片用作光照贴图时选择此选项
- Single Channel 当图片只需要一个通道时, 设置为单通道类型
在Texture Type中,最常用的就是UI中的图片Sprite(2D and UI),还有模型中的Default。
二、TextureType = Default
1.Texture Shape:
- 2D 所有纹理的最常见设置. 将图像文件定义为 2D 纹理. 用于将纹理映射到 3D 网格, GUI 以及其他元素
- Cube 将图像文件定义为立方体贴图. 可以将其应用于天空盒子等.
2.sRGB (Color Texture)
启用此属性, 可以指定图片文件存储在伽马 (γ) 空间中. 相对为线性空间. 默认勾选.
3.Alpha Source
定义如何生成图片的 Alpha 通道.
- None 无论图片文件是否包含 α 通道信息都不导入 α 通道
- Input Texture Alpha 使用图片文件中的 Alpha 通道信息
- From Gray Scale 根据图像文件的 RGB 平均值来生成 Alpha 通道信息
4.Alpha Is Transparency
勾选此选项之后, Unity 会覆写全透明像素的 RGB 值为临近不透明像素 RGB 的值, 通过这种方式使这些像素存储的 RGB 与临近像素一致, 减少 纹理过滤 时产生的瑕疵.
参考聊聊 Unity 的 Alpha Is Transparency 有什么用
5.Remove Matte (PSD)
对使用透明度 (将彩色像素与白色混合) 的 Photoshop 文件启用特殊处理. 仅当 *.psd 文件时有效.
6.Ignore PNG file gamma
启用此属性可以忽略 PNG 文件中的 Gamma 属性.
7.Non Power of 2
如果图片的大小不是 2 的幂, 这将定义在导入时的缩放行为, 共有 4 个选项.
- None 不进行任何的缩放, 纹理尺寸大小保持不变
- ToNearest 纹理在导入时将被缩放到最近的幂大小. 例如 257x511 纹理将成为 256x512. 注意: PVRTC 格式要求纹理是正方形, 因此最终大小将变换到 512x512
- ToLarger 纹理在导入时将被缩放到下一个较大的幂大小. 例如 257x511 纹理将成为 512x512
- ToSmaller 纹理在导入时将被缩放到下一个较小的幂大小. 例如 257x511 纹理将成为 256x256
[注意] 可以在 Unity 中使用 NPOT (非 2 的幂) 纹理大小. 但是, NPOT 纹理大小通常会占用更多的内存, 并且 GPU 采样的速度可能会更慢, 因此, 在可能的情况下, 最好使用两种大小的幂 (宽高都是 2 个幂) 来提高性能.
通常仅应将 NPOT 大小用于 GUI
8.Read/Write Enabled
只有启用此属性之后才可以在脚本中使用 Texture2D.SetPixels 以及 Texture2D.GetPixels 还有一些其他的 Texture2D 方法访问 Texture 数据.
在内部, Unity 使用 Texture 数据的副本进行脚本访问, 意味着这个选项会使 Texture 所需的内存量增加一倍. 因此, 此属性默认情况下处于禁用状态, 并且仅在需要脚本访问权限时才应启用它.
9.Virtual Texture Only
图片仅用作虚拟图片. 通常情况下 Unity 会将纹理既作为 Texture2D (可从脚本访问), 又作为可流式纹理, 选中此选项之后, 仅作为可流式纹理使用, 不可以从脚本访问此纹理.
10.Streaming Mip Maps
启用此属性以在此 Texture上 使用 Mip Map Streaming.该设置对于 Unity 用 Mesh Renderer 显示的 3D 环境中的任何 Texture 都有效.漫反射贴图, 法线贴图和光照贴图对 Mip Map Streaming 均有效.
Mip Map Priority 此数值设置 mipmap 的优先级. Unity 在分配内存资源时使用它来确定要优先处理的 mipmap. 值越大优先级越高.
11.Generate Mip Maps
启用此属性可启用 Mip 映射生成. Mip 贴图是 Texture 的较小版本, 勾选此属性之后, 此纹理的内存占用将会增大 33%, 但是此纹理在远近不同距离下的性能消耗也会变低, 因此需要看项目中是否需要使用内存空间来换取更好的性能表现.
- Border Mip Maps 启用此属性可避免颜色渗出到较低 Mip 级别的边缘.
- Mip Map Filtering 贴图过滤. 有两种方法可以使用 mipmap 过滤来优化图像质量: Box 和 Kaiser
- Box: Mip 级别随着尺寸的减小而变得更加平滑.
- Kaiser: 当 mipmap 的尺寸减小时, 将对它们进行锐化算法.
- Mips Maps Preserve Coverage 如果希望生成的 mipmap 的 alpha 通道在 alpha 测试期间保留覆盖率, 请启用此属性.
- Alpha Cutoff Value: 在 Alpha 测试期间控制 Mip Map 覆盖范围的参考值.
- Fadeout Mip Maps 淡出贴图. 启用此属性可使 Mip 贴图随着 MIP 级别的提高而淡化为灰色. 这用于局部贴图.
- Fade Range, 范围滑动条, 最左边的滚动条是开始淡出的第一个 MIP 级别, 最右边的滚动条定义纹理完全变灰的 MIP 级别.
12.Wrap Mode
变换模式. 选择在平铺的时候纹理的行为.
- Repeat 在 Tile 时重复平铺纹理
- Clamp 拉伸纹理的边缘
- Mirror 在每个整数边界处镜像纹理以创建重复图案
- Mirror Once 镜像一次纹理, 然后将其钳位到边缘像素
- Per-axis 选择此选项可单独控制 Unity 在 U 轴和 V 轴上的 Wrap Mode
13.Filter Mode
过滤模式, 选择当纹理进行变换拉伸时如何对其进行过滤.
- Point (no filter) 邻近取样, 即不进行任何过滤, 适用于像素风格
- Bilinear 双线性, 纹理在附近显得模糊
- Trilinear 三线性, 与双线性类似, 但纹理在不同的 MIP 级别之间也会模糊
14.Aniso Level
使用 Anisotropic filtering (各向异性过滤) 方式对纹理进行过滤, 当以陡峭角度查看纹理时可提高纹理质量. 适用于地板和地面纹理, 缺点是会带来较高的性能成本. 因此通常情况下会将这个等级设置为 1 或者 0.
15.Max Size(建议2048)
设置导入的纹理的最大尺寸, 单位为像素.因为艺术家们通常更喜欢使用巨大尺寸大小的纹理, 但是在导入到 Unity 的时候可以将纹理缩小到合适的尺寸大小.
16.Resize Algorithm
当纹理尺寸大于指定的最大尺寸时, 用于缩小纹理尺寸的算法.
- Mitchell 使用 Mitchell 算法调整纹理的大小
- Bilinear 使用双线性插值调整纹理的大小, 如果图像中有很多很重要但是面积却很小的细节, 此时便可以使用这个选项, 这个方式可以保留比 Mitchell 更多的这些细节
17.Format
图片格式设置, 除了一些特殊要求, 自动即可
18.Compression
纹理的压缩类型. 根据平台和压缩格式的可用性, 不同的设置可能最终会具有相同的内部格式.例如, 低质量压缩会影响移动平台, 但不会影响台式机平台.
- None 不压缩纹理
- Low Quality 以低质量格式压缩纹理
- Normal Quality 以标准格式压缩纹理
- High Quality 以高质量格式压缩纹理
19.Use Crunch Compression
是否使用紧缩压缩来压缩纹理. 如果可用, 推荐使用此压缩.
Crunch 压缩方式是 DXT 或 ETC Texture 压缩之上的有损压缩格式, 展示图像时, Unity 在 CPU 上将纹理 "解压缩" 为 DXT 或 ETC, 然后在运行时将其加载到 GPU.
Crunch 压缩有助于 Texture 使用最小的磁盘空间和下载带宽.
Crunch 算法可能需要花费很长时间对纹理进行压缩, 但是运行时的解压缩速度非常快!
- Compressor Quality: 设置 Crunch Compression 的质量, 更高的压缩质量意味着更大的纹理和更长的压缩时间.
20.Split Alpha Channel
在以下平台上可以对 Texture 进行 Alpha 分割: tvOS, iOS, Lumin, Android.
21.Override ETC2 fallback
允许选择在不支持 ETC2 纹理格式的 Android 设备上将纹理解压缩到的纹理格式.
22.附录
LOD: Levels of Detail, 简称 LOD, 译为: 细节层次技术. 该技术通常对每一原始多面体模型建立几个不同逼近精度的几何模型, 与原模型相比, 每个模型都只保留了一定层次的细节, 在绘制模型时, 根据不同的标准选择适当的层次模型来表示物体. 远视的时候使用粗糙的模型, 近视的时候使用精细的模型.
HUD: 游戏开发中一般用来指代仅用来向玩家显示游戏中各种信息的 UI. 原意是: 平视显示器.
Mip Map: Mip 贴图, 是一个包含了一个图像逐渐变小的多个版本的列表 (类似 LOD). 当纹理使用 Mip 贴图时, Unity 会在距离相机很远的地方自动使用较小版本的纹理, 这样便可以降低渲染纹理的性能成本并且又不会造成细节损失; 另外 Mip 贴图还可以减少纹理混叠和闪烁. 但是启用 mipmaps 会额外占用 33% 的内存, 因此仅应在会根据摄像机距离而改变的纹理上使用它, 禁止在不会改变的纹理上使用它, 例如 UI 纹理, 天空盒等都禁止使用.
Normal maps: 法线贴图. "法线贴图着色器" 使用 "法线贴图" 使低多边形模型看起来像包含更多的模型细节一样, 使模型的外观更加精细; 另外 Unity 中使用的是编码为 RGB 图像的法线贴图.
Alpha maps: 阿尔法贴图, 就是指仅包含 Alpha 信息的 Texture. 可以使用 Alpha 贴图对材质应用不同级别的透明度.
三、TextureType = Sprite (2D and UI)
很多属性在上面已经说过了,现在主要看不一样的部分:
1.Sprite Mode
- Single:单图;
- Multiple:多图;
- Polygon:多边形,在SpriteEditor里使用多边形裁剪精灵;
2.Pixels Per Unit
单位距离内的像素点,一般默认100是有些大的,可以通过修改该参数来改变在世界内的大小。
3.Mesh Type
参考Unity Texture Mesh Type 选项
MeshType 只针对于 SpriteRenderer 有效, 如果不使用这个设置哪个选项都无所谓啦
- FullRect 网格数少,如果生成的物体数量很多,用这个比较好
- Tight 网格数多但是根据alpha 裁剪了透明的网格,减少了渲染, 如果图片是少量存在并且超级大,用这个比较合适。
4.Extrude Edges
参考UGUI性能优化——图集(上),不过我没看懂干啥的。
选择此值以基于像素阿尔法值生成网格。Unity生成的网格通常遵循Sprite的形状。
5.Sprite Editor
如果点击后,出现弹窗需要安装,参考Unity报错之 No Sprite Editor Window registered. Please download 2D Sprite package from Package Manager.,进行如下操作即可:Windows --> Package Manager-->2D Sprite,然后install即可。
6.九宫格
参考UGUI九宫格纹理拉伸的使用
设置好图片后,就可以把sprite赋值给ui,看效果去了,并将图片类型选择为sliced
7.分割图片(Sprite Mode选Multiple)
参考Unity 2DSprite和Unity中制作自定义字体的两种方式
分割之后Unity只是创建一个文件来记录有哪些图片,哪些坐标,并不是真正分割出一张张小图片在本地保存
四、Image
参考关于Unity中UI中的Image节点以及它的Image组件
- SourceImage:把图片设置好后拖进Image节点的Source Image属性中,点击Set Native Size按照图片的原始大小填充Canvas。
- Color:可以对图片进行颜色混合,白色就是什么色也不加,原色。
- Material: Unity支持自定义图片材质来实现复杂的效果,不填的话默认只用unity已经设置好的UI材质效果。在游戏设计中几乎不会修改这里的内容。
- RaycastTarget: 勾选该选项后,该UI将会响应射线点击,鼠标点击到这个UI物体的时候事件管理器知道我们点击了什么物体,这个参数会和Button组件配合,完成我们的点击操作。
1.Image Type
- simple缩放的类型是拉伸
- Tiled缩放的类型是平铺,像铺地板瓷砖一样的。
- Slice缩放的类型是九宫格缩放,就像微信聊天的气泡一样,只有部分拉伸。原理就是把图片分成九宫格那样的区域,四个边角不变,只改变中间的区域,中间的横和中间的竖。这样缩放之后,再把四个边角贴上去,整体形状就不会改变。
- Filed指定区域显示,垂直,水平,圆周。比如一个圆,可以指定它只显示一个半圆,或者四分之一圆显示。经常用于游戏中的圆形进度条显示。
- Filed Method:(1)Radial 90 (2)Radial 180 (3)Radial 360按照角度来裁剪,一般是按照360度裁剪的。 (4)Vertical垂直裁剪 (5)Horizontal水平裁剪
- Filed Origin:开始的点,Button就是中间底部的那个点开始,不断变换圆心角来裁剪圆。
- Filed Amount:表示裁剪的比例多少[0,1],0到1进度条是递增的,1到0进度条是递减的。
- Clock Wise:逆时针还是顺时针,勾选的时候是顺时针
2.maskable
没搞懂干嘛的
五、SpriteRenderer
参考
(1-2)Unity3D/2D:Sprite Renderer组件详解
https://docs.unity.cn/cn/2020.3/Manual/class-SpriteRenderer.html
和Image类似的属性不再说了
1.Flip
有X和Y两个勾选项,可以通过勾选 Flip属性 对Sprite沿X和Y 方向 进行翻转,这样的翻转方式只会影响Sprite本身,而不会翻转其碰撞体和其子对象。而通过Transform控件的Rotation属性的X和Y 轴 实现翻转效果的方式,就会同时翻转其碰撞体和其子对象。
2.【Material属性】
默认为Sprites-Default材质,此时在Scene中Sprite不会受到光源系统的影响。可以通过 Material属性 使用其他的材质来达到不同的渲染效果,并能受到光源系统的影响。
3.【Sorting Layer属性】
可以通过 Sorting Layer属性 设置多个分类图层,其中高图层的Sprite会被先渲染,然后低图层的Sprite被后渲染,并能覆盖高图层的Sprite而显示在其上方。
六、Sprite和UI Image的区别
参考
SpriteRenderer(场景_UI)和Image(Canvas_UI)的区别
Unity中Sprite和UI Image的区别
Unity2D:Sprite和Image的区别
如图,将一张图片直接拖到Scene和放到Image上,都可以在场景中看到,那么区别是什么呢
- 渲染上:Image 通过UGUI的Image和CanvasRenderer组件组件来渲染,Sprite 通过SpriteRenderer组件来渲染。两者在视觉上没有任何区别(都使用默认材质时)。它们默认的渲染也都是在Transparent Geometry队列中。
- 使用上:Image需要位于某个Canvas下才能显示出来。场景中的Sprite可以像普通的3D游戏物体一样对待,通过Transform组件进行移动等操作,而Image则使用RectTransform进行布局,以便通过Canvas统一管理。由于RectTransform可以设置大小、对齐方式等,Image可以说更加方便一点,这也是很多人选择使用Image的原因。
-
在引擎的处理上:将Wireframe选项打开然后在场景中观察,就可以清楚地发现,Image为一个矩形的Sprite生成两个三角形拼成的矩形几何体,而Sprite则会根据显示内容,裁剪掉元素中的大部分透明区域,最终生成的几何体可能会有比较复杂的顶点结构。
那么这种不同会造成什么结果呢?在继续之前,我们先回顾一下游戏中每帧的渲染过程。对任何物体的渲染,我们需要先准备好相关数据(顶点、UV、贴图数据和shader参数等等),然后调用GPU的渲染接口进行绘制,这个过程称作Draw Call。GPU接收到DrawCall指令后,通过一系列流程生成最终要显示的内容并进行渲染,其中大致的步骤包括:
- CPU发送Draw Call指令给GPU;
- GPU读取必要的数据到自己的显存;
- GPU通过顶点着色器(vertex shader)等步骤将输入的几何体信息转化为像素点数据;
- 每个像素都通过片段着色器(fragment shader)处理后写入帧缓存;
- 当全部计算完成后,GPU将帧缓存内容显示在屏幕上。
通过上面的认知,我们可以推断:
- Sprite由于顶点数据更加复杂,在第1/2步时会比Image效率更低;
- Sprite会比Image执行较多的顶点着色器运算;
- Image会比Sprite执行更多的片段着色器运算;
看起来似乎Image比Sprite有更大的好处,然而事实上,由于片段着色器是针对每个像素运算,Sprite通过增加顶点而裁剪掉的部分减少了相当多的运算次数,在绝大多数情况下,反而比Image拥有更好的效率 —— 尤其是场景中有大量的2D精灵时。
总结一下,SpriteRenderer会创建额外的几何体来裁剪掉多余的透明像素区域,从而减少了大量的片段着色器运算,并降低了overdraw;而Image则会创建简单的矩形几何体。随着2D元素数量的增加,这种差别会慢慢明显起来。
可以看出,SpriteRenderer确实是经过优化以显示更多的元素的。所以在2D游戏开发中,游戏场景中的元素,应该尽量使用它去渲染。而Image应该仅用于UI显示(实际上即使不考虑性能原因,由于屏幕分辨率的变化,Image可能会被Canvas改变显示位置和实际大小,如果用于游戏内元素的显示,可能会造成跟预期设计不一致的显示结果,也应该避免使用)。
七、RawImage
参考
Unity3d随笔之Rawimage和Image
UGUI系列——RawImage应用
表面上看这两个其实也并没有什么不同嘛,资源都是一张图片,资源也都可以正常显示,那么这两者究竟有何不同呢?
首先两者在实现方式上有差异,Image的代码实现更为复杂,功能也更为丰富,在image组件里,我们可以实现资源的不同的Image Type,有四种,Simple,Sliced,Tiled和Filled。这四种Image Type有各自的应用场景,这个如果有一定的项目经验就会有所了解。
这里我们也是简单说一下吧,Simple顾名思义,简单,也就是不做处理,也是我们默认的一种Type。Sliced,切割,这个是我们在项目中经常会用到的一种Type,它在图片资源的九宫拉伸时会起到很好的效果。Tiled,平铺,这个也是需要进行九宫拉伸才会体现它的效果,Filled,填充,这个的应用场景大多是用于倒计时或者进度条的增长。具体的这四种Type的详细介绍,参考U3d随笔之ImageType。
以上说的这些,在Rawimage组件里是没有的,所以大家在上面的我们不是很详细的描述里,应该可以总结出两者在应用场景上的一个差别,前者,也就是Image,大多应用于某个ui的图片显示或者说是一些小图,比如我们刚说的需要拉九宫的图以及用作进度条和倒计时的图,而后者,只有一个Texture和通过UV Rect控制显示,这里的UV Rect就是通过简单的裁剪UV让图片显示部分,所以适合大背景的图进行使用,当然这里我们也有必要说明,被设置为Sprite的资源也可以被赋值给Rawimage,但是Rawimage本质上取得就是这个资源的Texture,其他的属性它都不关心,所以我们在平常进行使用的时候,尽量不要混用,Sprite和Texture尽量还是要分开。
1.UV Rect
x,y,w,h的值的取值范围是0到1的,也就是他们代表的实际是百分比
先将W,H设置为1,然后拖动X,Y观察结果:
XY控制偏移(正数向左向下,负数向右向上)
- 比如x=0.2表示把图片向左移动20%
- y=0.5表示把图片向下移动50%
WH控制缩放
- 比如W = 0.5表示 图片横向扩大为原来的2倍
- H = 2 表示图片纵向缩小为原来的0.5
2.小地图
利用Camera的属性 Target Texture,可以指定一个图片给摄像机,这个摄像机什么都不看,只看这个地图。
创建另外一个Camera并创建一个Cube,将Camera对准Cube进行观察,并设置Target Texture
现在将这个render Texture指给Canvas上的Raw Image,就是小地图了: