参考教程
Tutorial 38: Hardware Tessellation
学习记录
这篇文章主要介绍曲面细分(Tessellation)技术,本篇代码不多。主要在着色器方面,我们新增了两个着色器 HullShader
和 DomainShader
。
这一篇中,我们介绍在 DX11 中实现曲面细分,我们将使用线框模式画一个正方形:
经过细分以后,如下:
曲面细分,英文称Tessellation,如果直译的话应该译作“镶嵌化处理技术”。 由ATI开发,微软采纳后将其加入DirectX 11,成为DirectX 11的组成部分之一。 由于这种技术广泛的应用在曲面的几何处理上,因此国内翻译时通常译作“曲面细分”。 但实际上,这种技术不是只能用在曲面的细分处理上。
我们主要的代码增改都在着色器里,所以直接来看着色器代码吧,在 VertexShader
中,我们不再处理变换,而是直接将顶点属性传递给我们新增的 HullShader
:
1 | struct VertexInputType |
在 HullShader
阶段,我们从代码中传入一个 TessellationAmount
来控制细分级别,对正方形的两个三角形进行细分( 也可以直接细分四边形 ),我们的 HullShader
着色器接受一个 TessellationBuffer
:
1 | cbuffer TessellationBuffer |
其全部代码如下:
1 | cbuffer TessellationBuffer |
HallShader
阶段我们完成了曲面细分因子的设置和片元控制点的输入,之后会经过固定渲染的细分阶段,这个阶段无需编程。然后才会进入 DomainShader
阶段,也是我们要新增的第二个着色器程序。在 DomainShader
着色器中,我们对细分后的顶点进行变换,即我们之前在 VertexShader
阶段实现的内容在这里实现了:
1 | cbuffer MatrixBuffer |
需要注意的是在这里的时候我们的坐标操作都需要使用 domain
和 patch
计算得到。最后一个阶段自然是我们的像素着色器了,它和之前一样并没有改变。
想要观察到我们的曲面细分结果,我们需要使用线框模式绘制,因为直接绘制的画,会是这样:
诺。
在 D3DClass
中我们暂且修改光栅化的配置使其使用线框绘制:
1 | ... |
然后在 TextureShaderClass
中,新增两个着色器以及对应缓冲:
1 | class TextureShaderClass |
他们的创建什么的和顶点着色器这些并无区别,所以代码就不贴了(请注意我们两个缓冲的位置,MatrixBuffer
已经不在顶点着色器了)。
最后我们需要修改绘制图元,在 ModelClass
里修改为:
1 | deviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_3_CONTROL_POINT_PATCHLIST); |
最终我们在 GraphicsClass
调用他们的绘制并且传入 tessellationAmount
为 3 ,效果如下(我们使用的是三角形细分):