hlsl意外的结果

时间:2013-10-24 15:20:20

标签: c++ hlsl pixel-shader

我发现了一些奇怪的HLSL错误 - 或者Pix正在说废话:

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

如果我使用HLSL点功能,输出为(-0.0f)这是有意义的但是现在输出的acos是-0.0000675917(这就是Pix所说的 - 以及着色器输出的内容)这不是我的预期;

即使我自己计算dotproduct(A.x * B.x + A.y * B.y +等),结果仍为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卡上测试了它,结果相同。

1 个答案:

答案 0 :(得分: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;