Direct X 12 – Texture 贴图

9.5 FILTERS

9.5.1 Magnification 放大

贴图中的元素应该被当作是一张连续图像的离散颜色样本;不应将其认为是一个矩形的区域。所以问题是:如果贴图坐标(u,v)并不与贴图中的texel对应,那么会发生什么?假设,玩家放大了场景中的一面墙壁,使其覆盖整个屏幕。我们显示器的分辨率为1024×1024,而墙面贴图的分辨率为256×256。这也就是贴图放大,我们想用几个texel来覆盖很多像素。在我们的例子中,在每一个texel点之间将会存在4个像素点。当顶点贴图坐标被插值到三角形网格模型的每一个三角形上时,每一个像素点将会得到一个特殊的贴图坐标。因此,有些像素点并不能对应texel点。假设texel点之间的颜色值将通过插值运算来模拟。而硬件端,也就是显卡,支持两种插值方法:恒定插值和线性插值。一般来说,我们会使用线性插值。

下图则展示了两种插值方法在1D贴图中的使用:假设1D贴图有着256个采样点,且一个插值的贴图坐标为u=0.126484375。这个标准化的贴图坐标则等于0.126484375×256=32.38个texel。很明显,该坐标位于两个texel样本之间,所以我们必须使用插值运算来求得该样本。

上图(a)中,根据texel点,我们构建了一个函数来模拟texel点之间的颜色值;而该函数将取离该点最近的texel点的值作为该点的颜色值。上图(b)中,根据texel点,我们构建了一个线性插值的函数来模拟texel点之间的某一点的颜色值。

2D线性插值也被称为双线性插值,如下图所示。假设某一点位于四个texel之间,我们则在u轴和v轴分别做两次一维插值。

上图中,有4个texel点,分别为c(i,j)

c(i,j+1),c(i+1,j),c(i+1,j+1)。而我们想要使用插值来模拟c点的颜色,而该点位于4个texel点之间;c向右距离c(ij)有0.75个单位,向下距离c(ij)有0.38个单位。首先,我们通过两次一维插值分别求得点c(T)和c(B)的值。之后在c(T)和c(B)之间再次进行插值运算求得点c的值。

下图则膳食了恒定插值与线性插值的不同效果。很明显,恒定插值下的画面看上去更像马赛克。线性插值的贴图看上去更平滑,但显示效果仍然不好。

我们需要记住的是,在游戏中,如果玩家的camera是可以随意移动的,那没有方法可以避免贴图放大。在一定距离之外,贴图看上去很棒,但是当camera靠近时就会发现贴图越来越粗糙。有些游戏会限制camera与物体表面的距离,以避免贴图被放得太大。而唯一的解决办法只有使用更高分辨率的贴图。

在本书中,基于贴图坐标使用恒定插值来找到某一点的颜色值也被称为point filtering。如果使用线性插值来找到某一点的值则被称为linear filtering。point/linear filtering是DX的专业术语。

9.5.2 Minification 缩小

Minification缩小,正好是上一小节放大的反义词。也就是说太多的texel点被映射到了太少的像素点上。例如,场景中墙壁的贴图分辨率为256×256。我们将camera对准墙壁,并不断后退,墙壁将会越来越小,所覆盖的屏幕中的像素也越来越少。而现在,256×256个texel点将被映射到64×64个屏幕像素点上。这种情况下,基于贴图坐标的像素点将不能与贴图的texel匹配。所以我们仍然需要将恒定插值和线性插值运用于minification。然而对于minification,我们有更多的办法。比方说,对256×256个texel点进行降级采样,只取其中的64×64个texel点。而mipmap提供了类似的技术,其虽然需要额外的内存空间,但很高效。在初始化时或者创建asset时,分辨率更小的贴图将被制成mipmap链(如下图所示)。因此我们预先计算了mipmap的尺寸。在游戏运行时,硬件将会基于mipmap的设置做两件事:

1. 挑选并使用最匹配当前屏幕像素的mipmap,这也被称为mipmap的point filtering,因为其类似于恒定插值,我们只选择最相近的mipmap作为贴图。

2. 挑选并使用最匹配当前屏幕像素的2个mipmap(其中1个大于当前屏幕像素,而另1个小于当前屏幕像素)。之后将两个mipmap的进行插值运算。这也被称为mipmap的linear filtering,因为其类似于线性插值。

通过从mipmap链中选取最佳的贴图,minification的程度将被大大减少。

正如在之前的9.3.2小节提到的,mipmap可以使用PS的DDS插件生成,也可以使用texconv生成。这些程序都使用了降级采样的算法来来生成分辨率更低的图像。有时,这些算放无法保留美术所需要的细节,这样的话,我们就西药手动去创建mipmap了。

9.5.3 Anisotropic Filtering

另一种类型的filter被称为anisotropic filtering。该filter能够有效缓解当多边形的法线垂直于camera的方向向量时的画面变形。这一类型的filter开销最大,但是大大纠正画面的变形。下图展示了linear filtering和anisotropic filtering的区别。

上图中,木箱顶面的法线几乎是垂直于camera的方向向量(或者说垂直与窗口平面)。左边的木箱使用了linear filtering,但是画面明显模糊了。右边的木箱使用了anisotropic filtering,其画面效果更好。

《Direct X 12 – Texture 贴图》有5条留言

  1. 老铁,这本书的中译版正在走最后阶段,预计今年就要出版了……
    而且这本书坑很多,如果要翻译造福大家,请用心……
    谢谢!

    回复
    • 哈哈,中文版已经要出版啦,是在审核还是在翻译?是程序员翻译的么,还是那种大学老师翻译的?写这本书的老铁感觉没有写dx11时那么认真,里面有些东西直接从上一本拷过来。。坑的话我觉得还行吧,就是一些要点容易遗漏。。。

      回复
      • 已经在最后审核期了,大约几个月后就能出了吧~
        如果不是这些坑,这本书的中文版半年前可能就已经出来了……
        十分同意老铁的感觉,尤其是改得还不彻底,还漏了些东西。
        最坑的是阿三带领的微软团队,随着win10的更新方式的更改,隔半年就有新特性、新函数加进去,简直是坑神之神吗~ XD
        另外,题外话,就冲着win10,我感觉GitHub早晚要被微软玩儿坏……
        应该说算是程序员翻译的,之前做过相关的东西,我觉得中译本质量应该还算说得过去,如果出版社不坑的话……到现在,这本书已经翻译快满两年了,一个人翻译的……
        不管怎么说,也要感谢老铁在业余时间给大伙分享技术!
        DX 12与福尔康一样,偏底层,不好(容易)玩儿,到现在也没见有谁正经用它优化,做出什么强大的游戏来……
        您翻译的速度还真是挺快的……orz
        我记得今年八月rtr 4th就要来了,如果能翻译好,定是国内图形界的福音啦~ 🙂

        回复
        • 额。。。两年也太久了吧,辛苦啦,哈哈。我是觉得翻译的话,对书中知识点的理解挺有用的,如果只是粗略地看比较容易漏。。
          DX12可能还是微软自己旗下的工作室在用吧,这一个世代的xbx one肯定还是DX11为主。。看看下一代主机上新的话能不能普及DX12

          回复
          • 扎心啊,老铁!
            里面的事儿太多太杂,水深啊……如果愿意的话,届时买一本(估摸也不太可能……)看看就明白了……不过他马上就要弄完了,好歹算了了这件心事儿啦……据说裤衩都要当出去鸟……
            总是在黑暗的角落里暗想,这玩意儿也许他们自己也不会使的,驱动配合、无穷更新……统统加起来这玩意儿其实……
            嗯,这次1803倒没更新什么东西,说明相对趋于稳定了,或许这个节骨眼儿上发出中译本是个合适的时机?谁知道捏……
            最后再贫一句话,书里的错误有软有硬,所以就算是一字一句对着翻出来,结果也可想而知,这就是为什么这本要花那么长时间准备的原因之一啦,老铁!所以,我才会说如果要翻译给大家看,要用心啦……

留下评论

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据