曲面细分着色器学习记录
前言:
今天终于走通了Catlike大佬的曲面细分着色器教程,感慨一番,自己的学习之路还很漫长呢
今天的博客内容只是简单的记录一下Catlike大佬的教程
先上个链接:Catlike的曲面细分教程
什么是曲面细分
学习过建模的朋友们都一定知道曲面细分,在Blender中也有曲面细分修改器工具,用来细分图元,帮助我们获得更细腻的模型表面
闫令琪在Games101中的Geometry章节中也降到了曲面细分的原理(Loop细分和Catmull-Clark细分,我回顾了一下感觉和今天的原理不太一样)
渲染管线中的曲面细分着色器
1. 渲染流水线
乐乐女神在《入门精要》中说明,曲面细分着色器处于几何阶段,并且可编程控制,同时这是一个可以选的shader
2. 输入与输出:
- 输入:patch以及三角形索引,patch就是多个顶点的集合,可以指定一个patch包含几个顶点
- 输出:细分之后的顶点
3. shader组成
在曲面细分着色器中,包含三个部分:
Hull shader
Tessellation
Domain shader
这三者中,Tessellation操作是计算机进行的,我们不可以操作,因此,我们需要配置的就是Hull shader
和Domain shader
Hull shader
:准备曲面细分的方法等基础数据,传递给Tessellation后进行细分操作
Dmain shader
:对细分后的点进行处理,将其从重心坐标转到相应的空间(可以转到模型空间、投影空间等等)
Hull shader
Hull shader的结构与vert 或 frag shader的结构明显不同,除了一个主要的方法外,还需要在前定义5个属性,用来说明Hull应如何准备数据。
属性说明:
1.[UNITY_domain("tri")]
:这个属性可以指定patch的类型,除了tri(三角形)之外,还包括quad、isoline。
2.[UNITY_outputcontrolpoints(3)]
:输出的控制点的数量,不一定与输入数量相同,也可以新增控制点。
3.[UNITY_outputtopology("triangle_cw")]
:输出拓扑结构。有三种:triangle_cw(顺时针)、trianglle_ccw(逆时针)、line(线段)。
4.[UNITY_partitioning("fractional_odd")]
:分割模式。有三种:integer、fractional_even、fractional_odd。说白了就是integer只可以整数分割,剩余两者可以小数分割,一般都用odd,分割更自然。
5.[UNITY_patchconstantfunc("patchEdgeFunction")]
:一个函数,patchEgdeFunction是教程里的函数名,这个函数需要在前面自行定义,用来说明细分中,边和图元里面的点内的细分数量。
6.[maxtessfactor(64.0f)]
:上面的代码里没写,但是有一位知乎大佬说明了,在这里补充以下。最大细分度,告知驱动程序shader用到的最大细分度,硬件可能会针对这个做出优化。Direct3D 11和OpenGL Core都至少支持64。
Patch Constant Function
这个函数指定了一个patch如何细分,每个patch只调用一次这个函数,而不是每个控制点调用一次。Patch Constant Function
与Hull shader
并行运行。
为了确定如何细分三角形,GPU使用四个细分因子,三角形的每条边都有一个因子,三角形内部也有一个因子,这两种细分因子都具有相应的语义。
因此,需要为这个细分因子创建一个结构体:
struct TessellationFactors
{
float edge[3] : SV_TessFactor;
float inside : SV_InsideTessFactor;
};
现在,我们可以定义Patch Constant Function
函数了:
TessellationFactors MyPatchConstantFunction (InputPatch<VertexData, 3> patch) {
TessellationFactors f;
f.edge[0] = 1;
f.edge[1] = 1;
f.edge[2] = 1;
f.inside = 1;
return f;
}
上述的代码中,MyPatchConstantFunction
是函数的名称,传入的数据是patch,在函数中定义了每条边以及三角形内部的细分因子,最后输出TessellationFactors
。这里的细分因子的参数只是暂时的,可以根据不同需求更改: