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 の「長さ」関数は、Pix のベクトル (0、-0、-0、0) に対して 1 を返し、そのベクトルの HLSL 関数「any」も true を返します。これは、-0.0f != 0.0f を意味します。

他の誰かがこれらに遭遇し、おそらく私の問題の回避策を持っていますか? Intel HD Graphics 4600 と Nvidia カードでテストしましたが、結果は同じでした。

4

1 に答える 1

0

acos が悪い結果を返す主な理由の 1 つは、acos が -1.0 から 1.0 の間の値を取ることを常に覚えているためです。

したがって、値が少しでも (1.0 ではなく 1.00001) 超えると、正しくない結果が返される可能性があります。

この問題には、強制キャッピング、つまりチェックを入れることで対処します

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