2013-10-24 36 views
0

我发现了几个奇怪HLSL错误 - 或Pix的是告诉无义:HLSL意想不到ACOS导致

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

如果我使用HLSL点函数,输出是(-0.0f),这很有意义,但现在该输出的acos是-0.0000675917(这就是Pix说的 - 这是什么着色器输出)这不是我所期望的;即使我自己计算点积(A.x * B.x + A.y * B.y +等),结果仍然是0.0f,但是我的结果的最终结果并不为零。

我确实需要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卡上测试了它,结果相同。

+0

提供一个[较短,自成体系,正确的示例]这个问题(http://sscce.org)。 – Oswald

+0

如果对A = {0.0f,-1.0f,0.0f}和B {0.0f,0.0f,1.0f}使用HLSL点函数,并且输出为-0.0f(根据您的问题,这是有意义的) ,为什么你将错误归因于HLSL而不是'acos'函数? – Oswald

+0

你是什么意思*似乎有长度1 *?你是如何测试它的? – Oswald

回答

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; 
+0

在这个问题中,'acos()'的输入接近'0'(它是两个正交向量的点积)。 – Oswald

+0

它应该是0,它介于1.0和-1.0之间 –

相关问题