内容简介
Direct3D是微软公司DirectX SDK集成开发包中的重要组成部分,是编写高性能3D图形应用程序的渲染库,适用于多媒体、娱乐、即时3D动画等广泛和实用的3D图形计算领域。
本书围绕交互式计算机图形学这一主题展开,着重介绍Direct3D的基础知识和着色器编程的方法,并介绍了如何利用Direct3D来实现各种有趣的技术与特效,旨在为读者学习图形技术奠定坚实的基础。本书包括3部分内容。第一部分介绍数学知识,涵盖向量代数、矩阵代数和变换等内容。这是贯穿全书的数学工具,是读者需要掌握的基础内容。第二部分重点介绍Direct3D的基础知识,展示用Direct3D来实现绘图任务的基本概念与技术,如渲染流水线、纹理贴图、混合、曲面细分等。第三部分则利用Direct3D来实现各种有趣的特效,如实例化与视锥体剔除、阴影贴图、环境光遮蔽等。
本书适合希望通过Direct3D来学习3D编程的C++中级程序员阅读,也可供已对Direct3D有一定了解或具有非DirectX API使用经验的3D程序员参考。
作者简介
弗兰克·D·卢娜(Frank D. Luna),毕业于加利福尼亚大学欧文分校,获得数学学士学位,具备着超过15年的DirectX交互式图形学编程经验,著有3本DirectX畅销书,曾从事3D医疗可视化、3D建筑设计软件以及游戏相关工作。
目录
- 第 一部分 必备的数学知识
- 第 1章 向量代数 3
- 1.1 向量 3
- 1.1.1 向量与坐标系 4
- 1.1.2 左手坐标系与右手坐标系 5
- 1.1.3 向量的基本运算 6
- 1.2 长度和单位向量 8
- 1.3 点积 9
- 1.4 叉积 12
- 1.4.1 2D向量的伪叉积 13
- 1.4.2 通过叉积来进行正交化处理 13
- 1.5 点 14
- 1.6 利用DirectXMath库进行向量运算 15
- 1.6.1 向量类型 16
- 1.6.2 加载方法和存储方法 17
- 1.6.3 参数的传递 18
- 1.6.4 常向量 20
- 1.6.5 重载运算符 21
- 1.6.6 杂项 21
- 1.6.7 Setter函数 21
- 1.6.8 向量函数 23
- 1.6.9 浮点数误差 26
- 1.7 小结 28
- 1.8 练习 29
- 第 2章 矩阵代数 34
- 2.1 矩阵的定义 34
- 2.2 矩阵乘法 36
- 2.2.1 定义 36
- 2.2.2 向量与矩阵的乘法 37
- 2.2.3 结合律 37
- 2.3 转置矩阵 38
- 2.4 单位矩阵 38
- 2.5 矩阵的行列式 39
- 2.5.1 余子阵 40
- 2.5.2 行列式的定义 40
- 2.6 伴随矩阵 41
- 2.7 逆矩阵 42
- 2.8 用DirectXMath库处理矩阵 43
- 2.8.1 矩阵类型 44
- 2.8.2 矩阵函数 46
- 2.8.3 DirectXMath矩阵示例程序 47
- 2.9 小结 49
- 2.10 练习 49
- 第3章 变换 52
- 3.1 线性变换 52
- 3.1.1 定义 52
- 3.1.2 矩阵表示法 53
- 3.1.3 缩放 53
- 3.1.4 旋转 55
- 3.2 仿射变换 58
- 3.2.1 齐次坐标 58
- 3.2.2 仿射变换的定义及其矩阵表示 58
- 3.2.3 平移 59
- 3.2.4 缩放和旋转的仿射矩阵 61
- 3.2.5 仿射变换矩阵的几何意义 61
- 3.3 变换的复合 62
- 3.4 坐标变换 63
- 3.4.1 向量的坐标变换 64
- 3.4.2 点的坐标变换 65
- 3.4.3 坐标变换的矩阵表示 66
- 3.4.4 坐标变换矩阵及其结合律 66
- 3.4.5 坐标变换矩阵及其逆矩阵 67
- 3.5 变换矩阵与坐标变换矩阵 68
- 3.6 DirectXMath库提供的变换函数 69
- 3.7 小结 70
- 3.8 练习 71
- 第二部分 Direct3D基础
- 第4章 Direct3D的初始化 77
- 4.1 预备知识 77
- 4.1.1 Direct3D 12概述 77
- 4.1.2 组件对象模型 78
- 4.1.3 纹理格式 79
- 4.1.4 交换链和页面翻转 80
- 4.1.5 深度缓冲 81
- 4.1.6 资源与描述符 83
- 4.1.7 多重采样技术的原理 85
- 4.1.8 利用Direct3D进行多重采样 87
- 4.1.9 功能级别 88
- 4.1.10 DirectX图形基础结构 89
- 4.1.11 功能支持的检测 92
- 4.1.12 资源驻留 93
- 4.2 CPU与GPU间的交互 94
- 4.2.1 命令队列和命令列表 94
- 4.2.2 CPU与GPU间的同步 98
- 4.2.3 资源转换 100
- 4.2.4 命令与多线程 101
- 4.3 初始化Direct3D 102
- 4.3.1 创建设备 102
- 4.3.2 创建围栏并获取描述符的大小 104
- 4.3.3 检测对4X MSAA质量级别的支持 104
- 4.3.4 创建命令队列和命令列表 105
- 4.3.5 描述并创建交换链 105
- 4.3.6 创建描述符堆 107
- 4.3.7 创建渲染目标视图 108
- 4.3.8 创建深度/模板缓冲区及其视图 110
- 4.3.9 设置视口 114
- 4.3.10 设置裁剪矩形 115
- 4.4 计时与动画 116
- 4.4.1 性能计时器 116
- 4.4.2 游戏计时器类 117
- 4.4.3 帧与帧之间的时间间隔 118
- 4.4.4 总时间 120
- 4.5 应用程序框架示例 123
- 4.5.1 D3DApp类 123
- 4.5.2 非框架方法 126
- 4.5.3 框架方法 127
- 4.5.4 帧的统计信息 128
- 4.5.5 消息处理函数 130
- 4.5.6 “初始化Direct3D演示”程序 131
- 4.6 调试Direct3D应用程序 135
- 4.7 小结 137
- 第5章 渲染流水线 139
- 5.1 3D视觉即错觉? 140
- 5.2 模型的表示 141
- 5.3 计算机色彩基础 142
- 5.3.1 颜色运算 143
- 5.3.2 128位颜色 143
- 5.3.3 32位颜色 144
- 5.4 渲染流水线概述 145
- 5.5 输入装配器阶段 147
- 5.5.1 顶点 147
- 5.5.2 图元拓扑 147
- 5.5.3 索引 151
- 5.6 顶点着色器阶段 152
- 5.6.1 局部空间和世界空间 153
- 5.6.2 观察空间 156
- 5.6.3 投影和齐次裁剪空间 158
- 5.7 曲面细分阶段 164
- 5.8 几何着色器阶段 165
- 5.9 裁剪 165
- 5.10 光栅化阶段 167
- 5.10.1 视口变换 167
- 5.10.2 背面剔除 167
- 5.10.3 顶点属性插值 169
- 5.11 像素着色器阶段 170
- 5.12 输出合并阶段 170
- 5.13 小结 171
- 5.14 练习 171
- 第6章 利用Direct3D绘制几何体 175
- 6.1 顶点与输入布局 175
- 6.2 顶点缓冲区 178
- 6.3 索引和索引缓冲区 183
- 6.4 顶点着色器示例 187
- 6.5 像素着色器示例 192
- 6.6 常量缓冲区 195
- 6.6.1 创建常量缓冲区 195
- 6.6.2 更新常量缓冲区 198
- 6.6.3 上传缓冲区辅助函数 198
- 6.6.4 常量缓冲区描述符 201
- 6.6.5 根签名和描述符表 202
- 6.7 编译着色器 206
- 6.7.1 离线编译 208
- 6.7.2 生成着色器汇编代码 210
- 6.7.3 利用Visual Studio离线编译着色器 212
- 6.8 光栅器状态 213
- 6.9 流水线状态对象 214
- 6.10 几何图形辅助结构体 217
- 6.11 立方体演示程序 219
- 6.12 小结 229
- 6.13 练习 230
- 第7章 利用Direct3D绘制几何体(续) 235
- 7.1 帧资源 235
- 7.2 渲染项 238
- 7.3 渲染过程中所用到的常量数据 239
- 7.4 不同形状的几何体 242
- 7.4.1 生成柱体网格 244
- 7.4.2 生成球体网格 248
- 7.4.3 生成几何球体网格 249
- 7.5 绘制多种几何体演示程序 251
- 7.5.1 顶点缓冲区和索引缓冲区 252
- 7.5.2 渲染项 255
- 7.5.3 帧内资源和常量缓冲区视图 257
- 7.5.4 绘制场景 260
- 7.6 细探根签名 262
- 7.6.1 根参数 263
- 7.6.2 描述符表 264
- 7.6.3 根描述符 266
- 7.6.4 根常量 267
- 7.6.5 更复杂的根签名示例 269
- 7.6.6 根参数的版本控制 270
- 7.7 陆地与波浪演示程序 271
- 7.7.1 生成栅格顶点 273
- 7.7.2 生成栅格索引 274
- 7.7.3 应用计算高度的函数 275
- 7.7.4 根常量缓冲区视图 277
- 7.7.5 动态顶点缓冲区 279
- 7.8 小结 281
- 7.9 练习 282
- 第8章 光照 283
- 8.1 光照与材质的交互 283
- 8.2 法向量 285
- 8.2.1 计算法向量 286
- 8.2.2 变换法向量 288
- 8.3 参与光照计算的一些关键向量 289
- 8.4 朗伯余弦定律 290
- 8.5 漫反射光照 292
- 8.6 环境光照 292
- 8.7 镜面光照 293
- 8.7.1 菲涅耳效应 294
- 8.7.2 表面粗糙度 296
- 8.8 光照模型的概述 298
- 8.9 材质的实现 299
- 8.10 平行光源 304
- 8.11 点光源 304
- 8.12 聚光灯光源 306
- 8.13 光照的具体实现 306
- 8.13.1 Light结构体 307
- 8.13.2 常用辅助函数 308
- 8.13.3 实现方向光源 310
- 8.13.4 实现点光源 310
- 8.13.5 实现聚光灯光源 311
- 8.13.6 多种光照的叠加 312
- 8.13.7 HLSL主文件 313
- 8.14 光照演示程序 316
- 8.14.1 顶点格式 317
- 8.14.2 计算法线 317
- 8.14.3 更新光照的方向 319
- 8.14.4 更新根签名 320
- 8.15 小结 320
- 8.16 练习 321
- 第9章 纹理贴图 323
- 9.1 纹理与资源的回顾 324
- 9.2 纹理坐标 325
- 9.3 纹理数据源 328
- 9.3.1 DDS格式概述 328
- 9.3.2 创建DDS文件 329
- 9.4 创建以及启用纹理 330
- 9.4.1 加载DDS文件 330
- 9.4.2 着色器资源视图堆 331
- 9.4.3 创建着色器资源视图描述符 331
- 9.4.4 将纹理绑定到流水线 333
- 9.5 过滤器 335
- 9.5.1 放大 335
- 9.5.2 缩小 337
- 9.5.3 各向异性过滤 338
- 9.6 寻址模式 339
- 9.7 采样器对象 341
- 9.7.1 创建采样器 341
- 9.7.2 静态采样器 344
- 9.8 在着色器中对纹理进行采样 346
- 9.9 板条箱演示程序 347
- 9.9.1 指定纹理坐标 347
- 9.9.2 创建纹理 348
- 9.9.3 设置纹理 349
- 9.9.4 更新HLSL部分代码 349
- 9.10 纹理变换 352
- 9.11 附有纹理的山川演示程序 353
- 9.11.1 生成栅格纹理坐标 353
- 9.11.2 铺设纹理 355
- 9.11.3 纹理动画 355
- 9.12 小结 356
- 9.13 练习 356
- 第 10章 混合 359
- 10.1 混合方程 360
- 10.2 混合运算 360
- 10.3 混合因子 362
- 10.4 混合状态 363
- 10.5 混合示例 365
- 10.5.1 禁止颜色的写操作 365
- 10.5.2 加法混合与减法混合 366
- 10.5.3 乘法混合 366
- 10.5.4 透明混合 367
- 10.5.5 混合与深度缓冲区 368
- 10.6 alpha通道 368
- 10.7 裁剪像素 369
- 10.8 雾 371
- 10.9 小结 377
- 10.10 练习 377
- 第 11章 模板 379
- 11.1 深度/模板缓冲区的格式及其资源数据的清理 380
- 11.2 模板测试 381
- 11.3 描述深度/模板状态 382
- 11.3.1 深度信息的相关设置 382
- 11.3.2 模板信息的相关设置 383
- 11.3.3 创建和绑定深度/模板状态 384
- 11.4 实现平面镜效果 385
- 11.4.1 镜像概述 385
- 11.4.2 定义镜像的深度/模板状态 387
- 11.4.3 绘制场景 389
- 11.4.4 绕序与镜像 390
- 11.5 实现平面阴影 391
- 11.5.1 平行光阴影 391
- 11.5.2 点光阴影 393
- 11.5.3 通用阴影矩阵 394
- 11.5.4 使用模板缓冲区防止双重混合 394
- 11.5.5 编写阴影部分的代码 395
- 11.6 小结 396
- 11.7 练习 397
- 第 12章 几何着色器 402
- 12.1 编写几何着色器 402
- 12.2 以公告牌技术实现森林效果 408
- 12.2.1 概述 408
- 12.2.2 顶点结构体 410
- 12.2.3 HLSL文件 411
- 12.2.4 SV_PrimitiveID语义 416
- 12.3 纹理数组 417
- 12.3.1 概述 417
- 12.3.2 对纹理数组进行采样 417
- 12.3.3 加载纹理数组 418
- 12.3.4 纹理子资源 418
- 12.4 alpha-to-coverage技术 419
- 12.5 小结 421
- 12.6 练习 422
- 第 13章 计算着色器 425
- 13.1 线程与线程组 427
- 13.2 一个简单的计算着色器 428
- 13.3 数据的输入与输出资源 430
- 13.3.1 纹理输入 430
- 13.3.2 纹理输出与无序访问视图 430
- 13.3.3 利用索引对纹理进行采样 433
- 13.3.4 结构化缓冲区资源 435
- 13.3.5 将计算着色器的执行结果复制到系统内存 437
- 13.4 线程标识的系统值 441
- 13.5 追加缓冲区与消费缓冲区 442
- 13.6 共享内存与线程同步 443
- 13.7 图像模糊演示程序 445
- 13.7.1 图像模糊理论 445
- 13.7.2 渲染到纹理技术 448
- 13.7.3 图像模糊的实现概述 450
- 13.7.4 计算着色器程序 456
- 13.8 拓展资料 461
- 13.9 小结 461
- 13.10 练习 463
- 第 14章 曲面细分阶段 468
- 14.1 曲面细分的图元类型 469
- 14.2 外壳着色器 470
- 14.2.1 常量外壳着色器 470
- 14.2.2 控制点外壳着色器 473
- 14.3 镶嵌器阶段 474
- 14.3.1 四边形面片的曲面细分示例 475
- 14.3.2 三角形面片的曲面细分示例 475
- 14.4 域着色器 476
- 14.5 对四边形进行镶嵌化处理 477
- 14.6 三次贝塞尔四边形面片 481
- 14.6.1 贝塞尔曲线 482
- 14.6.2 三次贝塞尔曲面 484
- 14.6.3 计算三次贝塞尔曲面的相关代码 485
- 14.6.4 定义面片的几何形状 487
- 14.7 小结 489
- 14.8 练习 490
- 第三部分 主 题 篇
- 第 15章 构建第 一人称视角的摄像机与动态索引 493
- 15.1 重温取景变换 493
- 15.2 摄像机类 494
- 15.3 摄像机类中的方法实现选讲 496
- 15.3.1 返回XMVECTOR类型变量的方法 496
- 15.3.2 SetLens方法 497
- 15.3.3 推导视锥体信息 497
- 15.3.4 与摄像机相关的变换操作 498
- 15.3.5 构建观察矩阵 499
- 15.4 摄像机演示程序的若干注解 500
- 15.5 动态索引 502
- 15.6 小结 509
- 15.7 练习 509
- 第 16章 实例化与视锥体剔除 511
- 16.1 硬件实例化 511
- 16.1.1 绘制实例数据 512
- 16.1.2 实例数据 512
- 16.1.3 创建实例缓冲区 517
- 16.2 包围体与视锥体 519
- 16.2.1 DirectXMath碰撞检测库 520
- 16.2.2 包围盒 520
- 16.2.3 包围球 523
- 16.2.4 视锥体 524
- 16.3 视锥体剔除 529
- 16.4 小结 532
- 16.5 练习 533
- 第 17章 拾取 535
- 17.1 屏幕空间到投影窗口的变换 536
- 17.2 位于世界空间与局部空间中的拾取射线 539
- 17.3 射线与网格的相交检测 540
- 17.3.1 射线与轴对齐包围盒的相交检测 542
- 17.3.2 射线与球体的相交检测 542
- 17.3.3 射线与三角形的相交检测 543
- 17.4 应用例程 545
- 17.5 小结 546
- 17.6 练习 547
- 第 18章 立方体贴图 548
- 18.1 什么是立方体贴图 548
- 18.2 环境贴图 549
- 18.3 绘制天空纹理 552
- 18.4 模拟反射 556
- 18.5 动态立方体图 559
- 18.5.1 动态立方体图辅助类 561
- 18.5.2 构建立方体图资源 562
- 18.5.3 分配额外的描述符堆空间 562
- 18.5.4 构建描述符 564
- 18.5.5 构建深度缓冲区 565
- 18.5.6 立方体图的视口与裁剪矩形 566
- 18.5.7 设置立方体图摄像机 566
- 18.5.8 对立方体图进行绘制 568
- 18.6 用几何着色器绘制动态立方体图 571
- 18.7 小结 574
- 18.8 练习 574
- 第 19章 法线贴图 577
- 19.1 使用法线贴图的动机 577
- 19.2 什么是法线贴图 578
- 19.3 纹理空间/切线空间 580
- 19.4 顶点切线空间 582
- 19.5 在切线空间与物体空间之间进行转换 583
- 19.6 法线贴图的着色器代码 584
- 19.7 小结 588
- 19.8 练习 589
- 第 20章 阴影贴图 591
- 20.1 渲染场景深度 591
- 20.2 正交投影 594
- 20.3 投影纹理坐标 595
- 20.3.1 代码实现 597
- 20.3.2 视锥体之外的点 598
- 20.3.3 正交投影 598
- 20.4 什么是阴影贴图 599
- 20.4.1 算法描述 599
- 20.4.2 偏移与走样 600
- 20.4.3 百分比渐近过滤 603
- 20.4.4 构建阴影图 607
- 20.4.5 阴影因子 612
- 20.4.6 阴影图检测 614
- 20.4.7 渲染阴影图 614
- 20.5 过大的PCF核 615
- 20.5.1 ddx函数与ddy函数 616
- 20.5.2 较大PCF核问题的解决方案 616
- 20.5.3 较大PCF核问题的另一种解决方案 618
- 20.6 小结 619
- 20.7 练习 620
- 第 21章 环境光遮蔽 622
- 21.1 通过投射光线实现环境光遮蔽 623
- 21.2 屏幕空间环境光遮蔽 626
- 21.2.1 法线与深度值的渲染过程 626
- 21.2.2 环境光遮蔽的渲染过程 628
- 21.2.3 模糊过程 637
- 21.2.4 使用环境光遮蔽图 641
- 21.3 小结 642
- 21.4 练习 642
- 第 22章 四元数 644
- 22.1 复数回顾 644
- 22.1.1 定义 645
- 22.1.2 复数的几何意义 645
- 22.1.3 极坐标表示法与旋转操作 646
- 22.2 四元数代数 647
- 22.2.1 定义与基本运算 647
- 22.2.2 特殊乘积 648
- 22.2.3 性质 648
- 22.2.4 转换 649
- 22.2.5 共轭与范数 649
- 22.2.6 四元数的逆 650
- 22.2.7 极坐标表示法 651
- 22.3 单位四元数及其旋转操作 652
- 22.3.1 旋转算子 652
- 22.3.2 将四元数旋转算子转换为矩阵形式 654
- 22.3.3 将旋转矩阵变换为四元数旋转算子 655
- 22.3.4 复合 657
- 22.4 四元数插值 657
- 22.5 DirectX数学库中与四元数有关的函数 661
- 22.6 旋转演示程序 662
- 22.7 小结 667
- 22.8 练习 667
- 第 23章 角色动画 670
- 23.1 框架层次 670
- 23.2 蒙皮网格 674
- 23.2.1 定义 674
- 23.2.2 重新推导将骨骼变换至根坐标系的公式 674
- 23.2.3 偏移变换 675
- 23.2.4 驱动骨架运动 675
- 23.2.5 计算最终变换 677
- 23.3 顶点混合 679
- 23.4 从文件中加载动画数据 682
- 23.4.1 文件头 682
- 23.4.2 材质 683
- 23.4.3 子集 683
- 23.4.4 顶点数据与三角形 684
- 23.4.5 骨骼偏移变换 685
- 23.4.6 层次结构 685
- 23.4.7 动画数据 686
- 23.4.8 M3DLoader类 688
- 23.5 角色动画演示程序 689
- 23.6 小结 692
- 23.7 练习 694
- 附录A Windows编程入门 695
- A.1 概述 696
- A.1.1 资源 696
- A.1.2 事件、消息队列、消息以及消息循环 696
- A.1.3 图形用户界面 698
- A.1.4 Unicode 698
- A.2 基本的Windows应用程序 699
- A.3 讲解基本Windows应用程序的工作流程 702
- A.3.1 程序中的头文件、全局变量以及函数声明 702
- A.3.2 WinMain 703
- A.3.3 WNDCLASS结构体与实例注册 704
- A.3.4 创建并显示窗口 705
- A.3.5 消息循环 707
- A.3.6 窗口过程 708
- A.3.7 消息框函数 710
- A.4 一种更灵活的消息循环 710
- A.5 小结 711
- A.6 练习 711
- 附录B 高级着色器语言参考 713
- B.1 变量类型 713
- B.1.1 标量类型 713
- B.1.2 向量类型 713
- B.1.3 矩阵类型 714
- B.1.4 数组 716
- B.1.5 结构体 716
- B.1.6 typedef关键字 716
- B.1.7 变量的修饰符 717
- B.1.8 强制类型转换 717
- B.2 关键字与运算符 718
- B.2.1 关键字 718
- B.2.2 运算符 718
- B.3 程序中的控制流 720
- B.4 函数 721
- B.4.1 用户自定义函数 721
- B.4.2 内置函数 722
- B.4.3 常量缓冲区的封装规则 725
- 附录C 解析几何学选讲 728
- C.1 射线、直线以及线段 728
- C.2 平行四边形 729
- C.3 三角形 729
- C.4 平面 730
- C.4.1 DirectX数学库中平面的表示 731
- C.4.2 空间点与平面的位置关系 731
- C.4.3 构建平面 732
- C.4.4 对平面进行规范化处理 733
- C.4.5 对平面进行变换 733
- C.4.6 平面内离指定点最近的点 734
- C.4.7 射线与平面的相交检测 734
- C.4.8 反射向量 735
- C.4.9 反射点 735
- C.4.10 反射矩阵 736
- C.5 练习 737
- 附录D 参考资料 739