[C++]学习《DirectX12 3D 游戏开发实战》 第八天 利用 Direct3D 绘制几何体(续)

embedded/2024/11/14 3:58:23/

本章将介绍一些此书后面常会用到的绘图模式。首先讲解与绘图优化相关的内容,此处涉及“帧资源 (frame resource)”等概念。若采用帧资源,我们就得修改程序中的渲染循环,好处:不必在每一帧都刷新命令队列,继而改善 CPU 和 GPU 的利用率。

接下来,我们会提出渲染项 (render item) 的概念,并解析如何基于更新频率来划分常量数据。

此外,我们将研究根签名的更多细节,并学习其他两种根参数类型:根描述符根常量

最后,我们还会展示怎样绘制更为复杂的物体。

完成本章的学习后,将能够绘制出形如山川的表面,还有圆台、球体以及模拟波浪运动的动画。

目标

1. 学会一种无须每帧都要刷新命令队列的渲染流程,由此来优化程序的性能。

2. 了解另外两种根签名参数类型:根描述符和根常量。

3. 探索如何在程序中生成和绘制常见的几何体,如栅格、圆台和球体。

4. 研究怎样通过动态顶点缓冲区来更新 CPU 中的顶点数据,并且向 GPU 上传顶点的新位置信息。

内容整理

1. 帧资源

2. 渲染项

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

4. 不同形状的几何体

5. 绘制多种几何体演示过程

6. 细探根签名

7. 陆地与波浪演示程序

小结

1. 在每帧中等待 GPU 处理完队列中所有命令的做法效率极低,因为这种策略在某些时刻会导致 CPU 或 GPU 处于空闲状态。一种更有效的技巧是创建帧资源 (frame resource) —— 一个由每帧都需 CPU 来修改的资源所构成的环形数组。这种方法令 CPU 无需等待 GPU 结束当前的任务,即可继续处理下一帧的相关工作;对此,CPU 只需处理下一个可用的(即 GPU 没在使用中的)帧资源。如果 CPU 处理帧的速度总是快于 GPU,则 CPU 必在某些时刻等待 GPU 追赶上来,但此情景又正是我们所期盼的:不仅 GPU 的处理能力将得到充分的发挥,同时,多出来的 CPU 资源又总是可被游戏的其他部分,如 AI,物理模拟与游戏逻辑所利用。

2. 我们可以用 ID3D12DescriptorHeap::GetCPUDescriptorHandleForHeapStart 方法来获取堆中第一个描述符的句柄,通过 ID3D12Device::GetDescriptorHandleIncrementSize 方法得到描述符的大小(依赖于硬件与描述符的类型)。一旦知道了描述符增量的大小,我们就能用两种 CD3DX12_CPU_DESCRIPTOR_HANDLE::Offset 方法之一偏移至第 n 个描述符的句柄处:

// 指定要偏移到的描述符的编号,再将它乘以描述符的增量大小
D3D12_CPU_DESCRIPTOR_HANDLE handle = mCbvHeap->GetCPUDescriptorHandleForHeapStart();
handle.Offset(n * mCbvSrvDescriptorSize);// 或者用另一种等价实现,先指定要偏移到的描述符编号,再设置描述符的增量大小
D3D12_CPU_DESCRIPTOR_HANDLE handle = mCbvHeap->GetCPUDescriptorHandleForHeapStart();
handle.Offset(n, mCbvSrvDescriptorSize);

CD3DX12_GPU_DESCRIPTOR_HANDLE 类型有着同样的偏移方法。

3. 根签名定义了在绘制调用开始之前,需要与渲染流水线相绑定的资源,以及这些资源将被映射到的具体着色器输入寄存器。绑定到流水线的具体资源要根据着色器程序来确定。在创建 PSO 后,根签名与着色器程序的组合就开始生效了。根签名由一系列根参数所构成。根参数可以是描述符表根描述符根常量。描述符表在堆中指定了一块描述符的连续范围。根描述符用于直接绑定根签名中的描述符(此过程无需涉及描述符堆)。而根常量则用于直接绑定根签名中的常量数据。出于性能的原因,1 个根签名中所能容纳的数据大小被限制为最多 64 DWORD。每个描述符表占 1 DWORD,每个根描述符用 2 DWORD,而每个 32 位的根常量占用 1 DWORD。硬件会为每次绘制调用而自动保存根实参的快照。这样一来,我们就能在每次绘制调用的过程中安全地修改根实参了。但是,我们也应当尽量缩小根签名的规模,以此降低内存间数据的复制量。

4. 当顶点缓冲区的内容在运行时需要频繁更新(比如在每一帧,或每 1/30 秒就要更新一次),动态顶点缓冲区就派上了用场。我们可以使用 UploadBuffer 类来实现动态顶点缓冲区,但这次存储的是顶点数组,而非常量缓冲区数组。由于我们在每一帧都要从 CPU 向波浪动态顶点缓冲区上传新数据,所以需要将动态顶点缓冲区存为一种帧资源。在使用动态顶点缓冲区的过程中,难免会产生一些开销,这是因为新数据必将从 CPU 端内存回传至 GPU 端的显存。因此,在静态顶点缓冲区也可以胜任相同工作的情况下,它会比动态顶点缓冲区更受青睐。对此,Direct3D 的最新版本已经引进了一些新的特性,以减少动态缓冲区的使用。


http://www.ppmy.cn/embedded/136419.html

相关文章

系统聚类的分类数确定——聚合系数法

breast_cancer数据集分析——乳腺癌诊断 #读取乳腺癌数据 import pandas as pd import numpy as np from sklearn.datasets import load_breast_cancer data load_breast_cancer() X data.data y data.target.. _breast_cancer_dataset:Breast cancer wisconsin (diagnosti…

ThingsBoard规则链节点:RPC Call Reply节点详解

引言 1. RPC Call Reply 节点简介 2. 节点配置 2.1 基本配置示例 3. 使用场景 3.1 设备控制 3.2 状态查询 3.3 命令执行 4. 实际项目中的应用 4.1 项目背景 4.2 项目需求 4.3 实现步骤 5. 总结 引言 ThingsBoard 是一个开源的物联网平台,提供了设备管理…

C++研发笔记12——C语言程序设计初阶学习笔记10

本篇笔记是一篇练习文章,是对第二部分《初识C语言》的一个回顾,从而结束第二部分的学习。 题目一 关于C语言关键字说法正确的是:( ) A.关键字可以自己创建 B.关键字不能自己创建 C.关键字可以做变量名 D.typedef不是关键字 【参考答案…

Java项目实战II基于Spring Boot的酒店管理系统(开发文档+数据库+源码)

目录 一、前言 二、技术介绍 三、系统实现 四、文档参考 五、核心代码 六、源码获取 全栈码农以及毕业设计实战开发,CSDN平台Java领域新星创作者,专注于大学生项目实战开发、讲解和毕业答疑辅导 一、前言 随着旅游业的蓬勃发展,酒店行…

HARCT 2025 新增分论坛2:机器人系统智能控制

会议名称:机电液一体化与先进机器人控制技术国际会议 会议简称:HARCT 2025 大会时间:2025年1月3日-6日 大会地点:中国桂林 主办单位:桂林航天工业学院、广西大学、桂林电子科技大学、桂林理工大学 协办单位&#…

斯坦福医学部发布GPT润色本子教程

最近,斯坦福大学医学部在GitHub上发布了一份针对申请资源本子润色的详细指导,包括使用GPT和其他大型语言模型来提升学术写作质量的全面建议。本文将为大家梳理这些润色指令,帮助你更好地理解和利用AI工具来优化学术写作。 指令集合 1. 提升文…

Linux下的systemd/service

开机自启任务 一. 概述 systemd 是现代 Linux 系统中管理系统和用户服务的工具,可以创建一个 systemd 服务来实现开机自启的任务 二. 操作 1. 创建 systemd 服务文件 使用文本编辑器创建一个新的服务文件: sudo vim /etc/systemd/system/test.servi…

如何设置定时关闭或启动整个docker而不是某个容器

如果你想定时关闭和启动整个Docker服务,而不是单个容器,可以使用系统级别的定时任务(如Cron)来实现。以下是如何操作的具体步骤: 使用Cron来定时关闭和启动Docker服务 打开Cron表: 打开终端。输入 crontab -e 编辑当前…