根据三角形的朝向:三角形相对于观察者的朝向也被纳入考虑的范畴之中。位于物体轮廓边线上的三角形势必比其他位置的三角形拥有更多的细节。
根据粗糙程度:粗糙不平的表面较光滑的表面需要进行更为细致的曲面细分处理。通过对表面纹理进行检测可以预算出相应的粗糙度数据,继而来决定镶嵌化处理的次数。
[Story10(可点击)]给出了以下几点关于性能的建议。
如果曲面细分因子为1(这个数字意味着该面片不必细分),那么就考虑在渲染此面片时不对它进行细分处理;否则,便会在曲面细分阶段白白浪费GPU资源,因为在此阶段并不对其执行任何操作。
考虑到性能又涉及GPU对曲面细分的具体实现,所以不要对小于8个像素这种过小的三角形进行镶嵌化处理。
使用曲面细分技术时要采用批绘制调用(batch draw call,即尽量将曲面细分任务集中执行)(在绘制调用之间往复开启、关闭曲面细分功能的代价极其高昂)。
控制点外壳着色器控制点外壳着色器以大量的控制点作为输入与输出,顶点着色器每输出一个控制点,此着色器都会被调用一次。控制点外壳着色器的应用之一是改变曲面的表示方式,比如把一个普通的三角形(向渲染管线提交的3个控制点)转换为3次贝塞尔三角形面片。例如,假设我们像平常那样利用三角形对网格进行建模,就可以通过控制点外壳着色器,把这些三角形转换为具有10个控制点的高阶三次贝塞尔三角形面片。新增的控制点不仅会带来更加丰富的细节,而且能将三角形面片镶嵌细分为用户所期望的份数。这一策略被称之为N-patches方法(法线—面片方法,normal-patches scheme)或PN三角形方法(即(曲面)点—法线三角形方法,point-normal triangles,简写为PN triangles scheme)[Vlachos]。由于这种方案只需用曲面细分技术来改进存在的三角形网格,且无需改动美术制作流程,所以实现起来比较方便。对于本章前面两个演示案例来说,控制点外壳着色器仅充当一个简单的传递着色器,它不会对控制点进行任何的修改。
注意:驱动程序可能会对传递着色器进行检测与优化。
struct VertexOut { float3 PosL : POSITION; }; typedef VertexOut HullOut; // Tessellation_Quad_Integer_HS.hlsl [domain("quad")] [partitioning("integer")] [outputtopology("triangle_cw")] [outputcontrolpoints(4)] [patchconstantfunc("QuadConstantHS")] [maxtessfactor(64.0f)] float3 HS(InputPatch<VertexOut, 4> patch, uint i : SV_OutputControlPointID, uint patchId : SV_PrimitiveID) : POSITION { return patch[i].PosL; }通过InputPatch参数可以将面片的所有控制点都传至外壳着色器中。系统值SV_OutputControlPointID索引的是正在被外壳着色器处理的输出控制点。值得注意的是,输入的控制点数量与输出的控制点数量未必相同。例如,输入的面片可能仅含有4个控制点,而输出的面片却能够拥有16个控制点;这些多出来的控制点可以由输入的4个控制点所衍生。
上面的控制点外壳着色器还用到了以下几种属性。
domain:面片的类型。可选用的参数有tri(三角形面片)、quad(四边形面片)或isoline(等值线)
partioning:指定了曲面细分的细分模式。
integer:新顶点的添加或移除依据的是上取整的函数。例如我们将细分值设为3.25f时,实际上它将会细分为4份。这样一来,在网格随着曲面细分级别而改变时,会容易发生明显的跃变。
非整型曲面细分(fractional_even/fractional_odd):新顶点的增加或移除取决于曲面细分因子的整数部分,但是细微的渐变“过渡”调整就要根据细分因子的小数部分。当我们希望将粗糙的网格经曲面细分而平滑地过渡到具有更加细节的网格时,该参数就派上用场了。
pow2:目前测试的时候行为和integer一致,不知道什么原因。这里暂时不讲述。
outputtopology:通过细分所创的三角形的绕序
triangle_cw:顺时针方向的绕序
triangle_ccw:逆时针方向的绕序
line:针对线段的曲面细分
outputcontrolpoints:外壳着色器执行的次数,每次执行都输出1个控制点。系统值SV_OutputControlPointID给出的索引标明了当前正在工作的外壳着色器所输出的控制点。
patchconstantfunc:指定常量外壳着色器函数名称的字符串
maxtessfactor:告知驱动程序,用户在着色器中所用的曲面细分因子的最大值。如果硬件知道了此上限,就可以了解曲面细分所需的资源,继而在后台对此进行优化。Direct3D 11硬件支持的曲面细分因子最大值为64
镶嵌器阶段