Direct X 12 – Compute Shader

GPU被优化为从单一内存地址或者连续的内存地址来处理大量的内存(其也被称为streaming operation);这正好与CPU相反,CPU被设计为读取随机的内存空间Introduction to Direct Compute。此外,由于顶点和像素能被独立处理,GPU大多为平行架构;例如,NVIDIA的“Fermi”架构支持拥有512个CUDA核心,且32个CUDA核心包含16个多处理器。

阅读更多Direct X 12 – Compute Shader

Direct X 12 – Geometry Shader 几何着色器

假设我们并没有使用tessellation阶段,那么geometry shader就是一个位于顶点着色器和像素着色器之间的可选阶段。顶点着色器处理的是所有顶点,而geometry shader则处理所有的图元(primitives)。例如,如果我们正在绘制三角形列表,那么geometry shader就会处理列表中的每一个三角形T:

for(UINT i = 0; i < numTriangles; ++i)
    OutputPrimitiveList = GeometryShader(T[i].vertexList);

请注意每一个三角形的三个顶点会被传入geometry shader,而geometry shader将输出图元的列表。与顶点着色器不能够销毁或者创建顶点不同,geometry shader的主要作用就是创建或者销毁几何图元;这也让我们能够使用GPU实现一些有趣的效果。例如,输入到geometry shader的图元可以被延展为多个图元,或者geometry shader基于某些条件不去输出一些图元。请注意,输出的图元并不需要与输入的图元有着相同的类型;例如,geometry shader将一个点延展为一个平面(两个三角形)。

geometry shader所输出的图元由顶点列表定义。而离开geometry shader的顶点,其坐标位置必须已经被转换至齐次剪裁空间。在geometry shader之后,我们所拥有的顶点列表,其在齐次剪裁空间中定义了图元的类型。之后,这些顶点将被投影(透视除法),并被光栅化。

阅读更多Direct X 12 – Geometry Shader 几何着色器

Direct X 12 – Stenciling

stencil buffer也是一个“屏幕后”的buffer,我们可以使用该buffer来实现某些特殊效果。stencil buffer和back buffer以及depth buffer有着相同的分辨率,也就是说stencil buffer中的第ij个像素对应back buffer和depth buffer中的第ij个像素。在4.1.5小节中我们了解到,当stencil buffer确定时,其将被附加到depth buffer。正如stencil的字面意义,stencil buffer犹如一个模板,其可以禁止某些像素被绘制到back buffer中。

例如,当实现镜面效果时,我们需要把镜子前的物体进行反射;然而我们希望反射的图像只在镜面中显示。我们可以使用stencil buffer来禁用反射后物体的像素,除非其位于镜面内(如下图所示)。

上图中,左边的骷髅在镜面中的显示是正确的。而骷髅没有显示在墙面上是因为墙面部分的像素无法通过depth test。然而,墙面外的部分,我们还是能看到骷髅。右边的图像中,我们使用了stencil buffer,禁止其在被绘制在非镜面的区域。

stencil buffer和depth buffer的设置都由D3D12_DEPTH_STENCIL_DESC表示,我需要将其设为D3D12_GRAPHICS_PIPELINE_STATE_DESC::DepthStencilState。最有效的学习stencil buffer的方法就是研究现有的demo范例。

阅读更多Direct X 12 – Stenciling

Direct X 12 – Blending 融合

参考下图,我们在绘制每一帧的画面时,首先绘制地形,之后是木箱,之后地形和木箱的像素就会记录在back buffer中。接着,我们使用blending将水面的像素绘制到back buffer,这样水面的像素就会与地形和木箱的像素在back buffer中进行融合,通过这一系列的步骤,就能模拟出地形和木箱位于水面下的效果。在本章节中,我们将学习blending(融合)的技术,其能将我们正在光栅化的像素(就是所谓的起始像素)与之前已经光栅化至back buffer的像素(就是所谓的终点像素)相融合/结合。该技术让我们可以绘制那些半透明的物体,例如水和玻璃等等。

考虑到便于大家理解,作者默认Blending技术将会绘制到back buffer而不是render target。然而,在之后的章节我们将会学习,将物体绘制到“与显示不相关”的render target中。而对于该类型的render target的融合技术,其实与back buffer大同小异,只不过融合的对象并不是back buffer中的像素,而是其他render target中的像素。

阅读更多Direct X 12 – Blending 融合

Direct X 12 – Texture 贴图

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

阅读更多Direct X 12 – Texture 贴图

Direct X 12 – Lighting 光照

各位老铁观察下图中的两个球体。左边的球体不带光照效果,而右边的则带有光照效果。就像我们所看到的,左边的球体看上去十分扁平,或者说它根本就不是一个球体而是一个扁平的圆!但是,右边的球体看上去就是一个3D的物体,很明显,光照以及阴影效果将帮助我们了解物体的形状以及体积。事实上,我们的视觉系统依赖于光照和光线与物体材质的交互,因此,如何生成照片级的场景就是如何精确模拟物理光照模型。

阅读更多Direct X 12 – Lighting 光照

Direct X 12 – Drawing II

本章节介绍了一些常用的渲染模式,而之后书中的demo都将运用该模式。本章节开篇将介绍一种渲染的优化手段,我们称其为“frame resource(每一帧的资源)”。有了frame resource,我们将修改之前的渲染逻辑与循环,之后就不需要每一帧都flush command queue(让CPU闲置以等待GPU处理完所有command list)。此外,我们将试验更多的root signature并学习另外几种root parameter类型:root descriptor和root constants。最后,我们将展示如何绘制一些更为复杂的物体;在本章的最后,我们将绘制一个场景包含山丘,峡谷,圆柱体,球体和一个波浪模拟动画。

阅读更多Direct X 12 – Drawing II

Direct X 12 – Drawing

在上一章中,我们主要聚焦在渲染管线的理论知识和数学知识。在本章节中,我们将着重介绍DX12中用来组成渲染管线的各个接口以及函数,定义顶点与像素着色器,并将图元/图形提交至渲染管线进行绘制。通过这一章的学习,我们将能够使用DX12绘制一个3D的立方体。

阅读更多Direct X 12 – Drawing

Direct X 12 – Rendering Pipeline 渲染管线

本章节的主题是渲染管线(这tm不是废话嘛)。假设我们有了一个3D场景,并且有一个朝向和位置确定的camera,那么基于这个虚拟的camera,将整个3D场景转换为一张2D的图像的所有步骤就是所谓的渲染管线。这一章的内容更理论化一些,而在下一章节中,我们将会把这些理论只是转换为实践,也就是使用DX12来绘制3D场景。在我们开始学习渲染管线之前,我们必须搞清楚两点:第一,3D场景的假象(因为屏幕是2D的,但我们视觉上觉得画面上的物体是3D的);第二,什么代表了色彩以及色彩在DX12中的运算。

阅读更多Direct X 12 – Rendering Pipeline 渲染管线