0

我发现了一些奇怪的 HLSL 错误——或者 Pix 是在胡说八道:

我有 2 个正交向量: A = { 0.0f, -1.0f, 0.0f } 和 B { 0.0f, 0.0f, 1.0f }

如果我使用 HLSL 点函数,则输出为 (-0.0f),这是有道理的,但现在该输出的 acos 为 -0.0000675917(这就是 Pix 所说的 - 以及着色器输出的内容),这不是我所期望的;

即使我自己计算点积(Ax*Bx + Ay * By + 等),结果仍然是 0.0f,但我的结果的 acos 不为零。

我确实需要 acos 的结果尽可能精确,因为我想根据三角形法线和给定向量之间的角度为我的顶点着色。

float4 PS_MyPS(VS_OUTPUT input) : COLOR
{
float Light = saturate(dot(input.Normal, g_LightDir)) + saturate(dot(-input.Normal, g_LightDir));   // compute the lighting

if (dot(input.Vector, CameraDirection) < 0)     // if the angle between the normal and the camera direction is greater than 90 degrees
{
    input.Vector = -input.Vector;               // use a mirrored normal
}

float angle = acos(0.0f) - acos(dot(input.Vector, Vector));

float4 Color;

if (angle > Angles.x)                           // Set the color according to the Angle
{
    Color = Color1;
}
else if (angle > Angles.y)
{
    Color = Color2;
}
else if (angle >= -abs(Angles.y))
{
    Color = Color3;
}
else if (angle >= Angles.z)
{
    Color = Color4;
}
else
{
    Color = Color5;
}

return Light * Color;
}

它适用于 0.01 度以上的角度,但对于较小的值会给出错误的结果。

我发现的其他错误是:hlsl 中的“length”函数为 Pix 中的向量 (0, -0, -0, 0) 返回 1,并且该向量上的 HLSL 函数“any”也返回 true。这意味着 -0.0f != 0.0f。

有没有其他人遇到过这些,也许有解决我的问题的方法?我在 Intel HD Graphics 4600 和 Nvidia 卡上对其进行了测试,结果相同。

4

1 回答 1

0

acos 可能返回错误结果的主要原因之一是始终记住 acos 取值介于 -1.0 和 1.0 之间。

因此,如果该值稍微超过 (1.00001 而不是 1.0) ,它可能会返回不正确的结果。

我通过强制封顶来处理这个问题,即检查

if(something>1.0)
   something = 1.0;
else if(something<-1.0)
   something = -1.0;
于 2013-10-24T15:44:43.417 回答