我正在编写一个DX11 SM5.0地形船体着色器,就像Frank Luna的许多例子一样。在研究(线框)地形疯狂闪烁的原因时,我已经开始研究pow()函数的问题。
我计算曲面细分因子的代码是:
float CalcTessFactor(float3 p)
{
float d = distance(p, cameraPosition);
float s = saturate((d - 1000.0f) / (5000.0f - 1000.0f));
//return pow(2, (lerp(6, 1, s)));
return saturate((5000.0f - d) / 5000.0f)*64.0f;
}
硬编码的数字常量是我调试缩减的一部分。注释掉的行:“// return pow(...”是原始代码,我已将其替换为现在的行。
通过此替换,曲面细分完全稳定,并随着距离相机的距离而缩小。正如预期的那样,减少只是线性而不是对数,但至少它是有效的,很好地镶嵌细分并且没有闪烁的迹象。
使用原始代码,网格似乎在明显随机的镶嵌因子之间以帧速率切换。
有人可以建议可能出现的问题吗?
我的补丁常量函数是:
struct HullInputType
{
float3 position : POSITION;
float4 color : COLOR;
};
struct ConstantOutputType
{
float edges[4] : SV_TessFactor;
float inside[2] : SV_InsideTessFactor;
};
ConstantOutputType TerrainPatchConstantFunction(InputPatch<HullInputType, 4> patch, uint patchId : SV_PrimitiveID)
{
ConstantOutputType output;
// Compute midpoint on edges, and patch center
// order of vertices is: 0 1
// 2 3
float3 e0 = 0.5f*(patch[0].position + patch[2].position);
float3 e1 = 0.5f*(patch[0].position + patch[1].position);
float3 e2 = 0.5f*(patch[1].position + patch[3].position);
float3 e3 = 0.5f*(patch[2].position + patch[3].position);
float3 c = 0.25f*(patch[0].position + patch[1].position + patch[2].position + patch[3].position);
// Set the tessellation factors for the four edges of the quad.
output.edges[0] = CalcTessFactor(e0);
output.edges[1] = CalcTessFactor(e1);
output.edges[2] = CalcTessFactor(e2);
output.edges[3] = CalcTessFactor(e3);
// Set the tessellation factor for tessallating inside the quad.
output.inside[0] = CalcTessFactor(c);
output.inside[1] = output.inside[0];
return output;
}
答案 0 :(得分:1)
查看您的返回值。看起来你正在倒退。取消注释代码的价格。距离值的硬编码说1000.你应该得到一致的tesselation。如果你这样做,你应该没有闪烁。如果你断言或不断言它的功能函数不是那么你的距离向量是时髦的。
编辑:添加了我的细分功能以供参考。
struct VertexOut
{
float4 PosW : POSITION0;
float4 waterAttributes : POSITION2;
float4 direction : POSITION1;
// float4 wind : POSITION2;
float tessFactor : TESS;
};
//========================================================================================================================
[domain("tri")]
[partitioning("integer")]
[outputtopology("triangle_cw")]
[outputcontrolpoints(3)]
[patchconstantfunc("PatchHS")]
HullOut HSMain(InputPatch<VertexOut, 3> p,
uint i : SV_OutputControlPointID,
uint patchId : SV_PrimitiveID)
{
HullOut hout;
// Pass through shader.
hout.PosW = p[i].PosW;
hout.direction = p[i].direction;
hout.waterAttributes = p[i].waterAttributes;
// hout.wind = p[i].wind;
return hout;
}
PatchTess PatchHS(InputPatch<VertexOut, 3> patch,
uint patchID : SV_PrimitiveID)
{
PatchTess pt;
// Average tess factors along edges, and pick an edge tess factor for
// the interior tessellation. It is important to do the tess factor
// calculation based on the edge properties so that edges shared by
// more than one triangle will have the same tessellation factor.
// Otherwise, gaps can appear.
pt.EdgeTess[0] = 0.5f * (patch[1].tessFactor + patch[2].tessFactor);
pt.EdgeTess[1] = 0.5f * (patch[2].tessFactor + patch[0].tessFactor);
pt.EdgeTess[2] = 0.5f * (patch[0].tessFactor + patch[1].tessFactor);
pt.InsideTess = pt.EdgeTess[0];
return pt;
}