【引擎研究】纹理相关属性说明

【引擎研究】纹理相关属性说明

伽马与线性空间

伽马与线性空间都是一种颜色空间,也即颜色存储时的分布方式,伽马空间相比线性空间会更多的存储图片的暗色部分。

伽马空间现在是图片存储的标准格式。选择伽马空间的原因有两点:

  1. 早期阴极射线管(CRT)显示器的输出会比输入颜色看上去偏暗,所以需要抬高输入值。
  2. 人的眼睛对暗色比亮色更加敏感,所以更多的保存暗色,图片视觉效果也越保真。
  3. 如今的显示器虽然可以实现线性输入输出,但也继承了 CRT 显示器的非线性特性。

线性空间更符合现实光线的物理特性,所以着色器计算需要线性空间颜色。

sRGB

sRGB 是公认的标准伽马空间,所以 sRGB 也是图片的默认保存方式。

sRGB 的具体保存方式就是对原本的线性颜色值进行调色(y=x12.2y=x^{\frac{1}{2.2}}),从而牺牲亮色空间以存储更多暗色。

光照计算时需要线性颜色,因此使用 sRGB 纹理需先将颜色逆推转回线性空间(y=x2.2y=x^{2.2}),不然纹理就会看上去比原本亮的多。

mipmaps

mipmaps 是一种 GPU 采样策略。其先基于原纹理生成多张分辨率逐渐降低的小纹理,然后根据实际渲染时纹理在屏幕上的大小占比,选择其中最合适的纹理进行采样。

  1. 分辨率降低以 2 的倍数进行,mipmap 等级越高分辨率越小。
  2. 判断纹理占比大小的方式是通过DDXDDY函数来对比当前像素与旁边像素的 uv 变化率来确定的,屏幕占比越小,变化率越大,采样所用的 mipmap 等级越大。

mipmaps 可以解决纹理分辨率和实际显示分辨率不同导致的过采样问题,具体而言有以下两点:

  1. 减少过采样导致的性能浪费,因为分辨率越低的纹理采样性能越高。
  2. 解决过采样导致的显示异常(摩尔纹)。

为了存储额外的低分辨率纹理,mipmaps 会占用一定额外空间,如果纹理的使用常见不存在上述问题(如 UI),则不应该使用 mipmap 功能。

各向异性

各项异性指物体从不同角度来看其性质会有所不同,放在纹理中是指 uv 两个轴的变化率不同:

  • 如果正着看纹理,uv 双轴的变化率是差不多的,此时为各向同性。
  • 如果倾斜看纹理,uv 双轴变化率可能相差非常大,此时为各项异性。

默认情况下 mipmaps 只考虑正视情况,生成的 mipmap 会均匀的混合周围所有的点,但倾斜时相比正视所能看到的点数量和位置是不同的。继续用这样的 mipmap 采样就会错误采到本该消失的点,导致出现晕影,看起来就像远处被模糊了一样。

所以启用 mipmaps 后应默认启用各项异性功能。这样 mipmaps 会额外存储一些不同宽高缩放比的 mipmap 以应对倾斜采样的情况。各向异性等级越高,这种 mipmap 就越多,应对能力也就越强。

过滤模式

指示 GPU 如何采用纹理。

  • 点(无过滤):只取 uv 最近像素的颜色信息。
  • 双线性:取 uv 最近四个像素的颜色信息并混合。
  • 三线性:对最近两张 mipmap 进行双线性采样,然后再混合。

包裹模式

指示 GPU 当采样时的 uv 输入值超出 [0,1][0,1] 范围时如何处理。

  • 重复:对输入值取模以纠正回范围内。
  • 夹紧:将输入值限制在最大范围内。
  • 镜像:类似乒乓的方式将输入值纠正回范围。
  • 镜像一次:只在 [1,0][-1,0] 范围内镜像一次,其他范围使用夹紧。

参考资料


【引擎研究】纹理相关属性说明
https://bdffzi-blog.pages.dev/posts/3631212322.html
作者
BDFFZI
发布于
2024年6月11日
许可协议