Я нашел несколько странных ошибок HLSL — или Pix говорит ерунду:
У меня есть 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 моего результата не равно нулю.
Мне нужно, чтобы результат 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 возвращает 1 для вектора (0, -0, -0, 0) в Pix, а функция HLSL «любой» для этого вектора также возвращает true. Это будет означать, что -0.0f != 0.0f.
Кто-нибудь еще сталкивался с этим и, возможно, у меня есть обходной путь для моей проблемы? Я протестировал его на Intel HD Graphics 4600 и карте Nvidia с теми же результатами.
acos
? - person Oswald   schedule 24.10.2013