DirectX11新增了一个非常吸引人的新技术,就是曲面细分。曲面细分技术可以通过产生新的顶点模拟出更平滑的曲面。
下图是《古墓丽影9中》没有开启曲面的效果,可以看到人物模型轮廓比较僵硬,这是因为原模型的三角形面数较低造成的:
开启了曲面细分后,看到人物模型轮廓已经相当平滑了,使得游戏画面更加真实:
那为什么不直接在原模型中增加模型面数呢?
原因有如下三点:
- 动态LOD(levels of detail,细节层次),我们可以基于摄像机的远近和其它因素决定要产生的细节丰富度。如果我们离物体比较远,就没有必要产生那么多模型面数。
- 使物理和动画模拟更加高效。低面数模型来计算物理和动画,可以使得计算效率更加高,接着再曲面细分,达到更逼真的显示效果。
- 节约内存。我们可以节约硬盘容量、CPU内存、GPU显存,在计算的时候再凭空新增细节顶点。
DirectX11中曲面细分的相关的三个阶段位于顶点着色器和几何着色器之间,Hull Shader Stage 和 Domain Shader Stage 我们可以编写Hull Shader(外壳着色器)和Domain Shader(域着色器)来控制曲面细分,而Tessellator Stage是GPU自动完成的。
一、曲面细分设置
1.Tessellation基本图元
当我们需要曲面细分的时候,就不再是输入三角图元到IA输入装配阶段了。而是需要指定控制点的个数:
D3D11_PRIMITIVE_1_CONTROL_POINT_PATCH = 8,
D3D11_PRIMITIVE_2_CONTROL_POINT_PATCH = 9,
D3D11_PRIMITIVE_3_CONTROL_POINT_PATCH = 10,
D3D11_PRIMITIVE_4_CONTROL_POINT_PATCH = 11,
…
D3D11_PRIMITIVE_31_CONTROL_POINT_PATCH = 38,
D3D11_PRIMITIVE_32_CONTROL_POINT_PATCH = 39
二、曲面细分相关的着色器
1.Hull Shader
Hull Shader由两部分组成:
(1) Constant Hull Shader
(2) Control Point Hull Shader
(1) Constant Hull Shader
该着色器是用于描述每个Patch的tessellation因子,如SV_TessFactor边细分度、SV_InsideTessFactor内部细分度。
下面是一个根据摄像机位置距离顶点远近来决定细分程度的Constant Hull Shader:
struct PatchTess
{
float EdgeTess[4] : SV_TessFactor;
float InsideTess[2] : SV_InsideTessFactor;
};
PatchTess ConstantHS(InputPatch<VertexOut, 4> patch, uint patchID : SV_PrimitiveID)
{
PatchTess pt;
float3 centerL = 0.25f*(patch[0].PosL + patch[1