Direct X 12 – Texture 贴图

我们的demo正变得越来越复杂,越来越有趣,但是现实世界中的物体有着更多的细节,不单单是我们之前定义的每个物体的材质material。贴图映射(Texture Mapping)让我们将图像的数据映射到三角形网格模型的三角形上,因此也让增加了场景的细节程度,让场景看起来更为真实。例如,我们可以构建一个正方体,将贴图映射到它的每一面来让它看上去是一个木箱。(如下图所示)

目标:

1. 学习如何将贴图的一部分映射到三角形网格模型的三角形上。

2. 学会如何创建并让demo支持贴图。

3. 学习如何让贴图看起来更为平滑。

4. 学会如何通过address mode来多次tile贴图。

5. 学会如何将多张贴图进行组合并创建新的贴图和效果。

6. 学会如何通过贴图动画来生成一些基本的效果。

9.1 贴图与资源

其实我们在第4章就已经开始使用贴图了;depth buffer和back buffer就是2D贴图对象,并由接口ID3D12Resource表示,D3D12_RESOURCE_DESC::Dimension为D3D12_RESOURCE_DIMENSION_TEXTURE2D。为了便于理解,在本章节的第一部分,我们将回顾第4章中学到的许多关于贴图的知识。

一张2D贴图就是数据的矩阵。2D贴图的一个用处是存储2D图像数据,而贴图中的每个元素都存储了一个像素的颜色。然而,这并不是2D贴图唯一的用处;例如,另一种技术被称为法线映射,贴图中的每一个元素都存储了一个3D向量而不是颜色。所以,贴图的用处并不会局限于存储颜色。1D的贴图(D3D12_RESOURCE_DIMENSION_TEXTURE1D)就好像一维数组,而3D贴图(D3D12_RESOURCE_DIMENSION_TEXTURE3D)则类似于一个三维数组。1D,2D,3D贴图皆由接口ID3D12Resource表示。

贴图和buffer资源不同,buffer仅仅存储了一组数据;而贴图有mipmap level,而且GPU可以对其进行特殊处理,例如filter(筛选)和多重采样。由于贴图资源支持特殊处理,它们被限定为一种特定的数据格式,而我们知道buffer资源可以存储各种类型的数据。贴图所支持的数据格式为枚举类型DXGI_FORMAT。以下是一些范例:

1. DXGI_FORMAT_R32G32B32_FLOAT:每一个元素都包含3个32位浮点数。

2. DXGI_FORMAT_R16G16B16A16_UNORM:每一个元素都包含4个16位浮点数,范围[0,1]。

3. DXGI_FORMAT_R32G32_UINT:每一个元素都包含2个32位整型数。

4. DXGI_FORMAT_R8G8B8A8_UNORM:每一个元素都包含4个8位浮点数,范围[0,1]。

5. DXGI_FORMAT_R8G8B8A8_SNORM:每一个元素都包含4个8位浮点数,范围[-1,1]。

6. DXGI_FORMAT_R8G8B8A8_SINT:每一个元素都包含4个8位整型数,范围[-128,127]。

7. DXGI_FORMAT_R8G8B8A8_UINT:每一个元素都包含4个8位整型数,范围[0,255]。

字母R,G,B,A分别代表红色,绿色,蓝色和α。但是,就像我们之前提到的,贴图并不一定要存储颜色信息;例如,DXGI_R32G32B32_FLOAT,其包含3个32位浮点数成员,因此可以存储一个3D向量。还有无类型(typeless)的格式,其只是用来预留内存空间,之后当贴图被绑定至渲染管线时才确定被转换为何种数据;例如,DXGI_FORMAT_R8G8B8A8_TYPELESS预留了4*8位的空间(4个字节),但是其并未声明数据类型(例如,整型数,浮点数,无符号整型数)。

在DX的SDK文档中提到:在创建一个类型确定的资源时,便限定了该资源。这将有助于程序运行时拿到该资源[…]。因此,我们只有在真的需要无类型资源是才创建它;否则,还是应该创建类型确定的资源。

贴图可以被绑定至渲染管线的不同阶段;通常我们将贴图作为render target(例如,DX12绘制贴图),或者作为着色器资源(例如,贴图在着色器中被采样)。一张贴图既可以被用作render target也可以被用作着色器资源,但是并不是同时。绘制一张贴图,之后将其用作着色器资源,有一个函数名为render-to-texture将会带来一些有趣的效果,我们也将在之后的章节中学习这部分知识。对于一个被用作render target和着色器资源 的贴图,我们需要创建两个descriptor指向该贴图资源:1)一个descriptor位于render target heap(例如,D3D12_DESCRIPTOR_HEAP_TYPE_RTV),2)一个descriptor位于shader resource heap(例如,D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV)。大家别忘了之前我们也提到,一个shader resource heap同样可以存储constant buffer view/descriptor和unordered access view/descriptor。之后贴图资源可以被绑定为render target或者在root signature中被绑定至root parameter作为一个着色器输入参数(不过切记,这两个操作并不能同时发生):

// 绑定为render target
CD3DX12_CPU_DESCRIPTOR_HANDLE rtv = ...;
CD3DX12_CPU_DESCRIPTOR_HANDLE dsv = ...;
cmdList->OMSetRenderTargets(1, &rtv, true, &dsv);

// 绑定为着色器的root signature的输入参数
CD3DX12_GPU_DESCRIPTOR_HANDLE tex = ...;
cmdList->SetGraphicsRootDescriptorTable(rootParamIndex, tex);

资源的descriptor主要做了两件事:它们将告诉DX12该资源将被如何使用(例如,资源被绑定至渲染管线的哪个阶段)。如果在创建资源时,资源的格式被声明为无类型,那么我们在创建资源的descriptor时一定要确定资源的类型。因此,对于无类型的贴图资源,很有可能在渲染管线的某个阶段其成员为浮点数,在另一个阶段则为整型数;;其主要意味着数据的转换。

在本章节中,我们只考虑将贴图绑定为着色器资源,这样像素着色器就能够采样贴图并让像素点从中获取颜色。

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

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

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

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

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

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

留下评论

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