DirectX 12 3D游戏开发实战(目录)

目录

内容提要

前言

本书受众

预备知识

需要配备的开发工具以及硬件环境

使用DirectX SDK文档以及SDK示例

明确学习目的

例程与在线补充材料

第一部分

必备的数学知识

第1章 向量代数

        1.1 向量

        1.2 长度和单位向量

        1.3 点积

        1.4 叉积

        1.5 点

        1.6 利用DirectXMath库进行向量运算

        1.7 小结

        1.8 练习

第2章 矩阵代数

        2.1 矩阵的定义

        2.2 矩阵乘法

        2.3 转置矩阵

        2.4 单位矩阵

        2.5 矩阵的行列式

        2.6 伴随矩阵

        2.7 逆矩阵

        2.8 用DirectXMath库处理矩阵

        2.9 小结

        2.10 练习

第3章 变换

        3.1 线性变换

        3.2 仿射变换

        3.3 变换的复合

        3.4 坐标变换

        3.5 变换矩阵与坐标变换矩阵

        3.6 DirectXMath库提供的变换函数

        3.7 小结

        3.8 练习

第二部分 Direct3D基础

第4章 Direct3D的初始化

        4.1 预备知识

        4.2 CPU与GPU间的交互

        4.3 初始化Direct3D

        4.4 计时与动画

        4.5 应用程序框架示例

        4.6 调试Direct3D应用程序

        4.7 小结

第5章 渲染流水线

        5.1 3D视觉即错觉?

        5.2 模型的表示

        5.3 计算机色彩基础

        5.4 渲染流水线概述

        5.5 输入装配器阶段

        5.6 顶点着色器阶段

        5.7 曲面细分阶段

        5.8 几何着色器阶段

        5.9 裁剪

        5.10 光栅化阶段

        5.11 像素着色器阶段

        5.12 输出合并阶段

        5.13 小结

        5.14 练习

第6章 利用Direct3D绘制几何体

        6.1 顶点与输入布局

        6.2 顶点缓冲区

        6.3 索引和索引缓冲区

        6.4 顶点着色器示例

        6.5 像素着色器示例

        6.6 常量缓冲区

        6.7 编译着色器

        6.8 光栅器状态

        6.9 流水线状态对象

        6.10 几何图形辅助结构体

        6.11 立方体演示程序

        6.12 小结

        6.13 练习

第7章 利用Direct3D绘制几何体(续)

        7.1 帧资源

        7.2 渲染项

        7.3 渲染过程中所用到的常量数据

        7.4 不同形状的几何体

        7.5 绘制多种几何体演示程序

        7.6 细探根签名

        7.7 陆地与波浪演示程序

        7.8 小结

        7.9 练习

第8章 光照

        8.1 光照与材质的交互

        8.2 法向量

        8.3 参与光照计算的一些关键向量

        8.4 朗伯余弦定律

        8.5 漫反射光照

        8.6 环境光照

        8.7 镜面光照

        8.8 光照模型的概述

        8.9 材质的实现

        8.10 平行光源

        8.11 点光源

        8.12 聚光灯光源

        8.13 光照的具体实现

        8.14 光照演示程序

        8.15 小结

        8.16 练习

第9章 纹理贴图

        9.1 纹理与资源的回顾

        9.2 纹理坐标

        9.3 纹理数据源

        9.4 创建以及启用纹理

        9.5 过滤器

        9.6 寻址模式

        9.7 采样器对象

        9.8 在着色器中对纹理进行采样

        9.9 板条箱演示程序

        9.10 纹理变换

        9.11 附有纹理的山川演示程序

        9.12 小结

        9.13 练习

第10章 混合

        10.1 混合方程

        10.2 混合运算

        10.3 混合因子

        10.4 混合状态

        10.5 混合示例

        10.6 alpha通道

        10.7 裁剪像素

        10.8 雾

        10.9 小结

        10.10 练习

第11章 模板

        11.1 深度/模板缓冲区的格式及其资源数据的清理

        11.2 模板测试

        11.3 描述深度/模板状态

        11.4 实现平面镜效果

        11.5 实现平面阴影

        11.6 小结

        11.7 练习

第12章 几何着色器

        12.1 编写几何着色器

        12.2 以公告牌技术实现森林效果

        12.3 纹理数组

        12.4 alpha-to-coverage技术

        12.5 小结

        12.6 练习

第13章 计算着色器

        13.1 线程与线程组

        13.2 一个简单的计算着色器

        13.3 数据的输入与输出资源

        13.4 线程标识的系统值

        13.5 追加缓冲区与消费缓冲区

        13.6 共享内存与线程同步

        13.7 图像模糊演示程序

        13.8 拓展资料

        13.9 小结

        13.10 练习

第14章 曲面细分阶段

        14.1 曲面细分的图元类型

        14.2 外壳着色器

        14.3 镶嵌器阶段

        14.4 域着色器

        14.5 对四边形进行镶嵌化处理

        14.6 三次贝塞尔四边形面片

        14.7 小结

        14.8 练习

第三部分 主题篇

第15章 构建第一人称视角的摄像机与动态索引

        15.1 重温取景变换

        15.2 摄像机类

        15.3 摄像机类中的方法实现选讲

        15.4 摄像机演示程序的若干注解

        15.5 动态索引

        15.6 小结

        15.7 练习

第16章 实例化与视锥体剔除

        16.1 硬件实例化

        16.2 包围体与视锥体

        16.3 视锥体剔除

        16.4 小结

        16.5 练习

第17章 拾取

        17.1 屏幕空间到投影窗口的变换

        17.2 位于世界空间与局部空间中的拾取射线

        17.3 射线与网格的相交检测

        17.4 应用例程

        17.5 小结

        17.6 练习

第18章 立方体贴图

        18.1 什么是立方体贴图

        18.2 环境贴图

        18.3 绘制天空纹理

        18.4 模拟反射

        18.5 动态立方体图

        18.6 用几何着色器绘制动态立方体图

        18.7 小结

        18.8 练习

第19章 法线贴图

        19.1 使用法线贴图的动机

        19.2 什么是法线贴图

        19.3 纹理空间/切线空间

        19.4 顶点切线空间

        19.5 在切线空间与物体空间之间进行转换

        19.6 法线贴图的着色器代码

        19.7 小结

        19.8 练习

第20章 阴影贴图

        20.1 渲染场景深度

        20.2 正交投影

        20.3 投影纹理坐标

        20.4 什么是阴影贴图

        20.5 过大的PCF核

        20.6 小结

        20.7 练习

第21章 环境光遮蔽

        21.1 通过投射光线实现环境光遮蔽

        21.2 屏幕空间环境光遮蔽

        21.3 小结

        21.4 练习

        第22章 四元数

        22.1 复数回顾

        22.2 四元数代数

        22.3 单位四元数及其旋转操作

        22.4 四元数插值

        22.5 DirectX数学库中与四元数有关的函数

        22.6 旋转演示程序

        22.7 小结

        22.8 练习

第23章 角色动画

        23.1 框架层次

        23.2 蒙皮网格

        23.3 顶点混合

        23.4 从文件中加载动画数据

        23.5 角色动画演示程序

        23.6 小结

        23.7 练习

附录A Windows编程入门

        A.1 概述

        A.2 基本的Windows应用程序

        A.3 讲解基本Windows应用程序的工作流程

        A.4 一种更灵活的消息循环

        A.5 小结

        A.6 练习

附录B 高级着色器语言参考

        B.1 变量类型

        B.2 关键字与运算符

        B.3 程序中的控制流

        B.4 函数

附录C 解析几何学选讲

        C.1 射线、直线以及线段

        C.2 平行四边形

        C.3 三角形

        C.4 平面

        C.5 练习

附录D 参考资料

Direct3D是微软公司DirectX SDK集成开发包中的重要组成部分,是编写高性能3D图形应用程序的渲染库,适用于多媒体、娱乐、即时3D动画等广泛和实用的3D图形计算领域。

本书围绕交互式计算机图形学这一主题展开,着重介绍Direct3D的基础知识和着色器编程的方法,并介绍了如何利用Direct3D来实现各种有趣的技术与特效,旨在为读者学习更高级的图形技术奠定坚实的基础。本书包括3部分内容。第一部分介绍必备的数学知识,涵盖向量代数、矩阵代数和变换等内容。这是贯穿全书的数学工具,是读者需要掌握的基础内容。第二部分重点介绍Direct3D的基础知识,展示用Direct3D来实现绘图任务的基本概念与技术,如渲染流水线、纹理贴图、混合、曲面细分等。第三部分则利用Direct3D来实现各种有趣的特效,如实例化与视锥体剔除、阴影贴图、环境光遮蔽等。

本书适合希望通过Direct3D来学习3D编程的C++中级程序员阅读,也可供已对Direct3D有一定了解或具有非DirectX API使用经验的3D程序员参考。


谨以此书献给我的侄辈们——

Marrick、Hans、Max、Anna、Augustus、Presley以及Elyse

Direct3D 12是一款为运行在现代图形硬件上的各种Windows 10平台(Windows桌面版、手机版和Xbox One)编写高性能3D图形应用程序的渲染库。Direct3D也是一种底层库,这也就意味着此种应用程序接口(API)与其下层控制的图形硬件模块关系更为紧密。Direct3D的主要用户大多来自游戏产业,他们驾驭Direct3D来构建更加高端的渲染引擎。同时,它亦应用于如医药产业、科学可视化以及虚拟建筑漫游等行业,用来实现高性能的3D图形交互功能。另外,由于当今每一部新的个人电脑都已配备了现代图形设备,因此,非3D应用也开始逐步把计算密集型的工作移交至显卡来执行,以充分发挥其中GPU(Graphics Processing Unit,图形处理器)的计算能力。这就是众所周知的GPU通用计算(general purpose GPU computing)技术。对此,Direct3D也提供了用于编写GPU通用计算程序的计算着色器API。尽管Direct3D 12程序通常以原生的C++语言进行编写,但SharpDX团队正在致力于.NET包装器版的开发,因此,用户也可以从托管应用程序中来访问这一强大的3D图形API。

本书围绕交互式计算机图形学这个主题展开,关注于通过Direct3D 12来进行游戏的开发。读者将从中学到Direct3D的基础知识以及着色器编程的方法。阅读完本书之后,读者就可以继续学习更加高级的图形技术了。本书共分为3个主要部分。第一部分讲解了本书后续要用到的数学知识。第二部分展示如何用Direct3D来实现基本绘图任务,例如初始化Direct3D,定义3D几何图形,设置摄像机,光照,纹理,混合技术,模板技术,曲面细分技术,创建顶点、像素、几何图形以及计算着色器。第三部分则主要是利用Direct3D来实现各种有趣的技术与特效,例如动画角色网格、拾取技术、环境贴图、法线贴图、阴影贴图以及环境光遮蔽技术。

初学者最好按先后顺序通读全书。书中章节是按照由浅入深、逐步递进的顺序组织而成的。这样一来,读者便不会因过陡的学习曲线而如堕烟海。一般来讲,特定篇章中所用的技术与概念往往在之前的章节中有所交代。因此,读者最好在掌握了欲学习章节之前的所有内容后再继续前行。当然,有一定经验的读者可直接挑选感兴趣的部分进行阅读。

最后,部分读者可能会不禁琢磨:读完本书之后,究竟能够开发出何种类型的游戏来呢?这里对此给出的解释是:您最好亲自粗略地阅览此书,看看其中大概都在讲些什么内容。据此,基于本书所讲的技术知识再结合自己的聪明才智,至于能够开发出哪类游戏作品,想必这答案读者也就自会了然于胸了。

本书主要适合以下3类读者:

1.希望通过Direct3D最新版本来学习3D图形学编程的C++中级程序员。

2.具有非DirectX API(如OpenGL)使用经验,并希望学习Direct3D编程方面知识的3D程序员。

3.具有一定的Direct3D使用经验,并希望学习Direct3D最新版本的程序员。

需要强调的是,本书为重点介绍Direct3D 12、着色器编程以及3D游戏编程的读物,而并非是讨论一般计算机程序设计的读物。因此,读者需要具备下列预备知识:

1.高中程度的数学知识,比如代数、三角学以及(数学)函数等。

2.Visual Studio相关的使用技能,比如如何创建项目、为项目添加文件以及指定需要链接的外部库等。

3.中级C++编程技能以及数据结构知识,比如熟练地运用指针、数组、运算符重载、链表、继承、多态等。

4.熟悉使用Win32 API进行Windows编程还是很有必要的,可谓是学习本书的基础。但这一条并非是强制性要求,因为本书附录A中提供了Win32编程的相关入门知识。

下面是进行Direct3D 12编程的必备条件:

1.Windows 10操作系统。

2.Visual Studio 2015开发环境或其后续版本。

3.一款支持Direct3D 12的显卡(本书中的演示程序都已通过Geforce GTX 760平台的测试)。

Direct3D是一种规模庞大的API,将其所有的细节都在一本书中体现是不切实际的。因此,为了获得更为深入的API信息,学习DirectX SDK文档的查阅方法势在必行。DirectX SDK在MSDN上的最新文档为《Direct3D 12 Programming Guide》,即《Direct3D 12编程指南》。

图1所示的是在线文档的截图。

图1 DirectX文档中的《Direct3D 12编程指南》

DirectX文档涵盖了DirectX API的方方面面,因此,它是一种不可或缺的参考资料。然而,由于此文档对预备知识的讲解并不深入且假设读者对此有一定认识,因而导致它无法成为初学者最佳的学习工具。但是,随着DirectX每个新版本的发布,该文档也在日益完善中。

换言之,这个文档主要还是用作参考。假设用户碰到一个与DirectX有关的数据类型或函数,如函数ID3D12Device::CreateCommittedResource,并希望获取更多与之相关的信息,就可以方便地在该文档中搜索它,比如本示例中的函数(见图2),以得到更为细致的描述。

图2 获取函数的相关文档


注意

在本书中,我们会不时地指导读者去阅览文档以获取更多的有关细节。


我们还建议读者研究一下官方提供的Direct3D 12演示程序。

微软官方可能还会在此陆续增添更多的例程。除此之外,读者还可以去NVIDIA、AMD以及Intel的官方网站上查找与Direct3D 12有关的示例。

尽管我们努力遵循Direct3D 12的最佳实践,力图写出高效的代码,但本书中每个样例的主要目标还是为了阐述Direct3D中的基本概念以及演示图形编程技术。应当明确的是,写出最优代码并非本书最终目的,而且过分优化还可能导致原本意图明晰的代码变得含混不清,反而适得其反。希望读者将这一点铭记于心,尤其是在将书中例程代码合并到自己的项目中时,因此在此过程中,您可能为了追求程序更高的效率而重构代码。再者,为了把注意力集中在Direct3D API上,我们还在Direct3D之上构建了一层轻量级的框架。这就意味着我们很可能会在源代码中,以硬编码的数值与定义其他内容的方式来令程序得以运行。类似地,在大型的3D应用程序中,可能要在Direct3D的基础之上实现一款渲染引擎。但本书的主旨却是Direct3D API,而非设计渲染引擎。

读者可以登录本书的网站(www.d3dcoder.net和www.merclearning.com),以获取本书相关材料。在前者中,读者可以找到本书内所有例程的完整源代码以及项目文件。也可通过异步社区本书页面获取(www.epubit.com)。在大多数情况下,DirectX程序往往比较庞大,以至于不宜全部列入书中。因此,只得在书中嵌入与所讲内容密切相关的代码片段。为此,我们极力建议读者在学习相关的例程代码时去一睹它的全貌(为了便于读者学习,我们已将演示程序的规模尽量减小)。一般说来,在阅读过特定章节,并研究完所附演示代码后,读者应当能够自行独立地实现该章节中所述的例程。但事实上,一种更快捷的学习方法是在参考书籍和示例代码的同时,尝试着以自己的方式实现相关程序。

下载本书的源代码 DirectX 12 3D 游戏开发实战源码

首先,读者需要下载本书所用的源代码并将其保存在硬盘的某个文件夹之中。为了便于讨论,假设这个文件夹的路径为C:\d3d12book。在这里可以看到一系列文件夹,其中含有对应章节的例程项目。读者可能会注意到有个名为“Common”的文件夹,其中包含所有演示项目中都要复用的公共代码。现在便可以在源代码文件夹中新建一个文件夹,用来存放我们自己的例程,例如C:\d3d12book\MyDemos。随后,我们将基于本书中的例程框架在该文件夹中创建一个新的项目。


注意

事实上,读者自己设置的目录结构大可不必如此,这只不过是本书例程的结构而已。如果读者希望按自己的意愿来设置源代码文件,可以将演示项目放在任何地方,只要使Visual Studio能找到Common目录中的源代码即可。


创建一个Win32项目

首先运行VS15,接着在主菜单中依次选择File(文件)→New(新建)→Project(项目),如图3所示。

图3 创建一个新项目

在弹出的New Project(新项目)对话框(如图4所示)左侧Visual C++项目类型的树形控件中选择Visual C++Win32,再于右侧选择Win32 Project(Win32项目)。接下来,给项目起个名称,并指定项目文件夹的保存位置。别忘了取消默认选中的Create directory for solution(为解决方案创建目录)复选框。随后单击OK(确定)按钮。

图4 新项目的相关设置

接着,又会弹出一个新的对话框。其左侧有Overview(概述)和Application Settings(应用程序设置)两个选项。选择Application Settings,便会出现如图5所示的对话框。在这里,需要确保选择Windows application(Windows应用程序)选项和Empty project(空项目)复选框,之后再单击Finish(完成)按钮。至此,我们已成功创建了一个空的Win32项目,但在构建DirectX项目例程之前,我们还有一些事情需要做。

图5 应用程序的相关设置

链接DirectX库

通过在源代码文件Common/d3dApp.h中使用#pragma预处理指令来链接所需的库文件,如:

// 链接所需的d3d12库
#pragma comment(lib, "d3dcompiler.lib")
#pragma comment(lib, "D3D12.lib")
#pragma comment(lib, "dxgi.lib")

对于创建演示程序而言,该预处理指令使我们免于打开项目属性页面并在连接器配置项下指定附加依赖库。

添加源代码并构建项目

至此,项目已经配置完成。现在来为它添加源代码并对其进行构建。首先,将“Box”演示程序的源代码BoxApp.cpp以及Shaders文件夹(位于d3d12book\Chapter 6 Drawing in Direct3D\Box)复制到工程目录之中。

待复制完上述文件之后,我们以下列步骤来将源代码添加到当前的项目之中。

1.右键单击解决方案资源管理器下的项目名称,在弹出的下拉菜单中依次选择Add(添加)→Existing Item(现有项),将文件BoxApp.cpp添加到项目中。

2.右键单击解决方案资源管理器下的项目名称,在弹出的下拉菜单中逐步选择Add→Existing Item,前往读者放置本书Common文件夹的位置,并将此文件夹中所有的.h/.cpp文件都添加到项目之中。现在,方案资源管理器看起来应当与图6相同。

图6 添加“Box”例程所需源代码之后的解决方案资源管理器

3.再次右键单击解决方案资源管理器下的项目名称,从菜单中选择Properties(属性)。再从Configuration Properties(配置属性)→General(常规)选项卡下,将Target Platform Version(目标平台版本)设置为版本10.x,以令目标平台为Windows 10。接着单击Apply(应用)按钮。

4.大功告成!源代码文件现都已位于项目之中,读者可以在主菜单中选择Debug(调试)→Start Debugging(开始调试)进行编译、链接以及执行该演示程序。应用程序的执行效果应当与图7所示的一致。

图7 “Box”演示程序的效果


注意

Common目录下的大量代码都是构建本书例程的基石。所以,建议读者先不必忙于查看这些代码。待读到了本书中与之相关的章节后,再研究它们也不迟。

必备的数学知识

“世上之事,无数学则不可解。”

罗杰•培根(《大著作》第四部分,第一章《第一个区别》,1267年)

电子游戏试图向玩家呈现出一个虚拟的世界。然而,计算机从本质上来讲却是一种处理数据的精密仪器。那么问题来了:如何用计算机来表达游戏中虚拟的场景呢?解决的办法就是完全运用数学的方式来描述场景空间以及其中物体的交互。因此,数学在电子游戏的开发中起着至关重要的基础性作用。

在讲述必备知识的第一部分中,我们将介绍穿插于全书的数学工具。重点是向量(vector,物理学和工程学中亦常译为“矢量”)、坐标系(coordinate system)、矩阵(matrix)及其变换(transformation),这些工具将广泛用于本书的所有例程之中。除了对这些数学知识进行讲解以外,我们还将纵览由DirectX数学库所提供的相关类与函数,并示范它们的用法。

请注意,这些主题仅论述了本书后续需要掌握的一些基础内容,而有关电子游戏所需的数学知识却不止于此。对于期望学习更多与游戏相关数学知识的读者,我们推荐[Verth04]和[Lengyel02]。

第1章“向量代数”向量(vector)也许是计算机游戏中最基础的数学对象,没有之一了。例如,我们可以用向量表示位置、位移、方向、速度与力。在这一章中,我们将学习向量及其运算法则。

第2章“矩阵代数”矩阵(matrix)为变换提供了一种高效且紧凑的简化表达方式。在这一章中,我们将熟悉矩阵及其运算定义。

第3章“变换”这一章将考察缩放、旋转和平移这三种基本的几何变换。我们利用这些变换来操纵空间中的3D物体。另外,我们还将讲解坐标变换,以此在不同的坐标系之间转换几何体的坐标表示。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值