我正在按照许多示例(例如 Frank Luna 的示例)编写 DX11 SM5.0 地形船体着色器。在调查(线框)地形疯狂闪烁的原因时,我一直关注 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;
}