DirectX12(D3D12)基础教程七 深度模板视图\剔除\谓词
本章主要讲遮挡,作者认为比较复杂有难度的知识点,作为基础教程不会深入讲解。
GPU渲染管线
主要包括以下阶段
- 输入装配(IA):读取顶点数据 ,定义顶点数据结构
- 顶点着色(VS):变换顶点到屏幕空间,Shader程序VSMain()
- 曲面细分 & 几何着色(HS/DS/GS,可选)
- 光栅化(Rasterization):将 3D 物体转换为 2D 像素
- 像素着色(PS):计算最终颜色
- 输出合并(OM):写入颜色缓冲 & 深度缓冲
光栅化(Rasterization):指的是通过顶点数据找到屏幕中需要显示的像素的过程,通过光栅化,我们将空间上连续的线条转化为屏幕中离散的像素(顶点数据到像素点),由硬件实现。
比如 在光栅化阶段时 使用 Z-Buffer(深度缓冲) 进行深度测试(Depth Test),决定像素是否可见。流程:
- 片元深度值 与 Z-Buffer 进行比较
- 深度测试通过 → 继续执行像素着色器(PS)
- 深度测试失败 → 丢弃像素,不执行 PS
深度模板视图 (DSV)
深度模板视图用于访问深度缓冲和模板缓冲资源。深度缓冲用来存储每个像素的深度值,以此来判定哪些像素该被渲染,哪些该被舍弃。模板缓冲则存储每个像素的模板值,可用于实现如阴影、遮罩这类特效。
D3D12中的剔除(Culling)是指从渲染过程中排除那些不需要渲染的对象,以减少计算量和提高渲染效率。
深度缓冲
深度缓冲区(或 z-Buffer 缓冲区)存储深度信息,以控制渲染(而不是从视图中隐藏)哪些多 边形区域。
模板缓冲
模板缓冲区用于遮罩图像中的像素,以产生特殊效果。 掩码控制是否绘制像素。 特殊效 果包括合成、贴纸、溶解、淡化、滑动、轮廓描绘和剪影,以及双面模板。
模板缓冲通过模板测试来决定哪些像素点可以被渲染。当启动模板测试时,片段像素点的值与模板缓冲区中的值进行比较,根据比较结果决定该像素点是否应该被绘制。模板测试的具体过程包括设置参考值和掩码,并根据测试结果对模板缓冲区的值进行相应的修改
具体应用场景
- 镜像效果:在渲染镜子时,模板缓冲区可以用来阻止镜子范围以外的镜像部分被绘制,从而只显示镜子中的反射部分
- 遮罩效果:通过设置模板缓冲区的值,可以实现遮罩效果,只渲染特定区域的像素,从而实现一些特殊的图形效果
- 光照和阴影效果:模板缓冲区可以用于实现光照和阴影效果,通过在渲染过程中对模板缓冲区进行修改,可以模拟光照的效果
创建深度模板视图(DSV)
1. 填充D3D12_DEPTH_STENCIL_VIEW_DESC结构
2.填充 D3D12_CLEAR_VALUE结构 并 创建资源 (CreateCommittedResource())
3. 通过CreateDepthStencilView()创建 深度模板视图 (DSV)
剔除
剔除的定义和作用
剔除是指在渲染过程中,根据一定的规则,将那些不会出现在最终视图中的对象或面片从渲染列表中移除,从而减少GPU的工作量,提高渲染效率和帧率。剔除技术主要包括以下几种:
背面剔除(Backface Culling):这是最常见的剔除技术,它只渲染面向摄像机的面,背对摄像机的面则不进行渲染。背面剔除可以显著减少需要处理的几何体数量,因为大多数场景中的物体只有一面是可见的。
视锥体剔除(Frustum Culling):视锥体剔除是通过判断物体是否在摄像机的视锥体内来决定是否渲染该物体。只有完全在视锥体内的物体才会被渲染,这样可以有效减少不必要的渲染计算。
遮挡剔除(Occlusion Culling):遮挡剔除是通过预先计算的遮挡信息来决定哪些物体可以被其他物体遮挡而不需要渲染。这种方法通常用于静态场景,可以显著减少需要渲染的物体数量。
谓词
D3D12中的谓词(Predicate)主要用于控制渲染操作的条件执行。谓词可以是一个布尔表达式,用于决定是否执行某些渲染命令。在D3D12中,谓词通常与命令列表(Command List)一起使用,以实现条件渲染。
谓词在D3D12中的作用主要体现在以下几个方面:
1. 条件渲染:通过谓词,开发者可以控制渲染操作是否执行。例如,可以根据时间、用户输入或其他条件来决定是否渲染某个对象。
2. 性能优化:通过条件渲染,可以减少不必要的渲染操作,从而节省资源并提高渲染效率。
使用D3D12中的谓词通常涉及以下步骤:
定义谓词:创建一个布尔表达式或函数,该表达式根据特定条件返回true或false。
设置命令列表:在命令列表中设置谓词,指定哪些渲染操作需要基于该谓词的条件执行。
执行命令列表:当谓词条件满足时,命令列表中的相关渲染命令才会被执行。
void SetPredication([in, optional] ID3D12Resource *pBuffer,UINT64 AlignedBufferOffset,D3D12_PREDICATION_OP Operation
);
当 GPU 执行 SetPredication 命令时,它会提取缓冲区中的值快照。 缓冲区中数据的未来更改不会追溯性地影响预测状态。
如果输入参数缓冲区(pBuffer)为 NULL,则禁用预测。
D3D12 API 中不存在谓词提示;直接、计算和复制命令列表允许进行谓词。 源缓冲区可以位于任何堆类型(默认、上传、读取、自定义)。
D3D12代码示例http://GitHub - microsoft/DirectX-Graphics-Samples: This repo contains the DirectX Graphics samples that demonstrate how to build graphics intensive applications on Windows.其中D3D12PredicationQueries 示例渲染了两个四边形;其中一个会动起来,周期性地遮挡另一个。对于每个渲染的帧,执行一个二进制遮挡查询,并使用setpredicate API来有条件地绘制潜在遮挡的四边形。当查询确定四边形被完全遮挡时,不执行渲染(隐藏一个四边形)。
感谢大家的支持,如要问题欢迎提问指正。