我写了一个程序来画一行。
当我将相机移动到正z轴时,该线有时会消失(特别是当z轴大于10000时)。
有一些测试结果。
当z设置为20541时,可以看到该行。
当z设置为20542时,无法看到该行。
当z设置为30320时,可以看到该行。
当z设置为30321时,无法看到该行。
依此类推......
附上代码。怎么了?
P.S。 代码是由OpenGL 1.0编写的,但是当我用OpenGL 3.0 + glm库编写时,我仍然能得到相同的测试结果。
SELECT DISTINCT A.ID , C.Date
FROM IDTable A
INNER JOIN AccountTable B
ON B.AccountID = A.AccountID
INNER JOIN UserTable UT
ON UT.UserMnemonicID = A.AssignedTo
FULL OUTER JOIN Updates U
ON U.ID = A.ID
FULL OUTER JOIN (-- Update2, with latest date
select CInner.*, CMax.MaxDate
from Update2 CInner
inner join (-- Max date for every AccountID
select AccountID, max(Date) MaxDate
from Update2
group by AccountID) CMax
on CMax.AccountID = CInner.AccountID
and CMax.MaxDate = CInner.Date) C
ON C.AccountID = B.AccountID
WHERE A.StatusID NOT IN ('Complete','Open')
--Need help here to only return MAX date value:
AND C.Date=(SELECT MAX(C.Date) FROM Update2)
ORDER BY A.ID
答案 0 :(得分:0)
这个问题似乎是浮点运算的数值不稳定性。由于您正在投影精确位于远平面上的点,因此当浮点结果略大于预期结果时,它们会被剪切。
让我们假设一个C ++实现了gpu的基本功能:
public static string GetTimeZoneAbbreviation(DateTime time)
{
string timeZoneAbbr;
if(time.IsDaylightSavingTime() == true)
{
timeZoneAbbr = TimeZoneInfo.Local.DaylightName;
}
else
{
timeZoneAbbr = TimeZoneInfo.Local.StandardName;
}
return timeZoneAbbr;
}
现在使用您提供的值调用此函数时,我们得到以下结果:
glm::vec4 test_fp(float z)
{
//Construct matrices
auto ortho = glm::frustum(-0.1f, 0.1f, -0.1f, 0.1f, 0.1f, 1000.0f);
auto lookat = glm::lookAt(glm::vec3(0, 0, z), glm::vec3(0, 0, z - 1.0f), glm::vec3(0, 1, 0));
//We are only interested in the z-value
glm::vec4 tvec(0, 0, z - 1000.0f, 1);
//Calculate ndc vector
auto result = ortho * lookat * tvec;
//Homogenize
result /= result.w;
return result;
}
正如您所看到的,auto a = test_fp(20541.0); //< [0, 0, 1.00000000, 1]
auto b = test_fp(20542.0); //< [0, 0, 1.00000191, 1]
auto c = test_fp(30320.0); //< [0, 0, 1.00000000, 1]
auto d = test_fp(30321.0); //< [0, 0, 1.00000191, 1]
和b
的结果与数学正确结果不同,略高于1.0。由于大于1.0的值位于远平面后面,因此它们被剪掉并且不可见,这正是您所拥有的行为。