1.Texture Type / Texture Shape
2.sRGB
3.Alpha Source / Alpha Is Transparency
4.Non Power of 2
5.Read/Write Enabled
6.Wrap Mode
7.Filter Mode
1.Texture Type / Texture Shape

a.Default
万能类型, 适合测试或不确定时使用
b.Normal map
法线贴图专用, 选择后, Unity会将RGB颜色转换为法线向量的XYZ数据, 必须取消勾选sRGB
c.Editor GUI and Legacy GUI
用于旧版IMGUI的UI元素
d.Sprite(2D and UI)
2D精灵和UI元素专用, 可以设置精灵模式(Single, Multiple用于图集), 以及Pixels Per Unit(PPU)等
e.Cursor
用于自定义鼠标光标
f.Cookie
用于灯光剪影(Light Cookie)
g.Lightmap
光照贴图专用
h.Directional Lightmap
定向光照贴图
i.Single Channel
单通道贴图, 用于将特定通道(如R)解释为一种数据(如金属度、光滑度)
Texture Type 纹理的形状
a.2D: 普通2D图片
b.Cube: 用于天空盒和反射探头的立方体贴图
2.sRGB
a.勾选表示这是一张颜色贴图, 纹理在采样时会进行伽马校正, 从sRGB颜色空间转化到线性空间进行计算, 确保光照和颜色
混合正确; 绝大多数情况下, 颜色贴图都需要勾选
b.不勾选表示这是一张非颜色贴图(如金属度, 光滑度, 法线贴图, 高度图等), 这些贴图保存的是数值而非颜色, 需要保持
线性; 对于法线贴图和金属度贴图等必须取消勾选
3.Alpha Source / Alpha Is Transparency

1).Alpha Source - Alpha通道从哪里来
a.Input Texture Alpha 从图片文件自带通道来
b.From Gray Scale 从图片的灰度值计算而来
c.None 没有Alpha通道
2).Alpha Is Transparency - 要用Alpha通道来做透明度吗? 理解Alpha Is Transparency:
-> Alpha Is Transparency预乘alpha, 消除掉透明纹素对屏幕颜色值的影响
a.理解透明像素: 对于一个完全透明的像素, 它不应该对最终屏幕颜色有任何的贡献; 理想情况下, 这个像素的数据应该
- 颜色(R, G, B)无所谓是什么颜色, 因为完全透明, 所以颜色不会看到
- 透明度(A)为0表示完全透明
b.问题根源 - 纹理过滤(Texture Filtering): 当3D模型上的一个纹理被渲染时, 屏幕上的一个像素很少会完美地对准纹理
上的一个像素(纹理像素或Texel); 由于摄像机移动、模型旋转或纹理缩放, 屏幕像素通常会落在2x2、甚至更多个纹理像素
之间; 这时, GPU就会进行纹理过滤(Bilinear或Trilinear), 来混合这几个纹理像素的颜色, 计算出最终屏幕像素的颜色
- 现在, 危险的情况来了: 假设我们有一张透明纹理, 它的边缘有一个像素是白色但完全透明的(R=1, G=1, B=1, A=0)它的
旁边是一个红色且完全不透明的像素 (1, 0, 0, 1); 当GPU要计算它们之间一个半透明像素的颜色时, 它会分别对RGB通道和
A通道进行混合
- 混合计算可能如下:
混合后的颜色(RGB): (1,1,1) * 0.5 + (1,0,0) * 0.5 = (1, 0.5, 0.5)
混合后的透明度(A): 0 * 0.5 + 1 * 0.5 = 0.5
c.最终的混合 - 问题爆发
GPU要将这个半透明的淡粉色片段(1, 0.5, 0.5, 0.5)与背景色(比如是黑色, (0, 0, 0))进行混合; 标准的混合公式是:
最终颜色 = 源颜色 * 源Alpha + 目标颜色 * (1 - 源Alpha)
- 代入我们的值:
最终颜色 = (1, 0.5, 0.5) * 0.5 + (0, 0, 0) * (1 - 0.5) = (0.5, 0.25, 0.25)
最终屏幕上出现了一个灰粉色的边缘, 这个边缘就是由那个本应完全透明的白色像素(1, 1, 1, 0)贡献的白色(1,1,1)混合进
来的
- 核心问题
那个"白色透明"像素, 它的颜色值太高了; 在过滤过程中, 它的高亮度颜色"污染"了本应是纯红色的边缘
d.解决方案 - 预乘Alpha(勾选Alpha Is Transparency)
Unity通过勾选Alpha Is Transparency来启用预乘Alpha, 就是为了从根本上解决这个问题; 预乘的操作很简单: 在导入纹
理时, Unity会提前将每个像素的RGB值乘以它的A值; 让我们看看同样的例子, 经过预乘后会发生什么
- 预处理纹理:
白色透明像素(1, 1, 1, 0)变为(1*0, 1*0, 1*0, 0) = (0, 0, 0, 0) 黑色完全透明
红色不透明像素 (1, 0, 0, 1)保持不变(1, 0, 0, 1)
- 再次进行纹理过滤:
混合后的颜色(RGB): (0, 0, 0) * 0.5 + (1, 0, 0) * 0.5 = (0.5, 0, 0) 一个暗红色
混合后的透明度(A): 0 * 0.5 + 1 * 0.5 = 0.5 半透明
- 最终的混合:
最终颜色 = (0.5, 0, 0) * 0.5 + (0,0,0) * (1 - 0.5) = (0.25, 0, 0)
结果: 我们得到了一个暗红色的边缘, 它完美地融合在红色物体和黑色背景之间, 没有任何不和谐的白色!因为那个捣乱的
白色像素, 在预乘后变成了无害的黑色(0, 0, 0)
4.Non Power of 2

Non Power of 2当纹理尺寸不是2的幂, 应该如何缩放
a.None: 不缩放
b.ToNearest: 缩放到最接近2的幂尺寸
c.ToLarger: 缩放到更大的2的幂尺寸
d.ToSmaller: 缩放到更小的2的幂尺寸
5.Read/Write Enabled

Read/Write Enabled决定了是否允许你的游戏代码(C#脚本)在运行时读取和修改这张纹理的像素数据
a.开启: 可以修改, 但消耗更多内存
b.关闭: 不能修改, 但内存效率最高
默认情况下, 这个选项是关闭的, unity为了性能做的优化
当纹理被加载到内存后:
a.Read/Write Enabled = 关闭(推荐)
- Unity会为GPU准备一个高度优化的纹理数据
- 一旦上传到GPU的显存, Unity就觉得CPU不会再需要操作它了, 所以可能会释放或压缩掉在CPU内存中的原始数据副本
- 结果: 内存占用最小, 性能最佳
b.Read/Write Enabled = 开启(谨慎使用)
- Unity心想: "脚本可能随时要读/写这个纹理, 我得把原始数据留着"
- 于是, Unity会在内存中同时保留两份数据:
一份是给GPU用的优化后的数据
另一份是给CPU脚本使用的、未压缩的原始数据
- 结果: 纹理的内存占用几乎翻倍!
6.Wrap Mode

Wrap Mode表示纹理采样超出[0, 1]范围时的行为
a.Repeat: 重复纹理, 适用于地面, 墙壁等需要无缝拼接的贴图
b.Clamp: 边缘像素拉伸, 适用于UI背景或不需要重复的图片
7.Filter Mode

Filter Mode表示纹理被拉伸或缩小时如何采样
a.Point: 最近邻过滤, 像素感强烈, 适合像素风游戏
b.Bilinear: 双线性过滤
c.Trilinear: 三线性过滤