我发现,如果我将透视矩阵的远面距离定义为1,000,000,000,那么该范围内的所有对象都会被裁剪。Range of 100,000,000工作正常。有人能解释这个吗?我的意思是,它仍然不是近似的浮点数最大范围。还是我说错了?为了计算透视图,我使用了GLM库。没有固定的管道僵硬。
更新:(JAVA)透视矩阵计算:
public static Mat4 perspective(float fovy, float aspect, float zNear, float zFar) {
float range = (float) (Math.tan(Math.toRadians(fovy / 2.0f)) * zNear);
float left = -range * aspect;
float right = range * aspect;
float bottom = -range;
float top = range;
Mat4 res = new Mat4(0.0f);
res.matrix[0] = (2.0f * zNear) / (right - left);
res.matrix[5] = (2.0f * zNear) / (top - bottom);
res.matrix[10] = -(zFar + zNear) / (zFar - zNear);
res.matrix[11] = -1.0f;
res.matrix[14] = -(2.0f * zFar * zNear) / (zFar - zNear);
return res;
}发布于 2012-10-29 18:56:01
由于浮点数的精度非常有限,您所看到的是一个舍入问题。
虽然浮点数的范围很大(对于大多数实际应用来说是“无限的”),但它们的精度是有限的,远远低于相同大小的整数。单精度(32位) float可以表示略高于7位的十进制数。你可以有非常小的或大的(比你想象的还要大或小)的数字,但它们仍然只有7.22个有效的小数位数。
可以表示为介于999,999,900和1,000,000,100之间的单精度float的唯一数字是: 999999872,999999936,1000000000和1000000064。通过计算for循环中的整数变量、转换为float变量并打印出来,可以很容易地验证这一点。
这意味着例如999,999,950和999,999,951和999,999,999是完全相同的数字,所以999,999,950可能会被剪切,尽管它“明显”在剪切平面的前面。
编辑:
带有输出的小演示程序:
#include <stdio.h>
int main()
{
float f = 0.0f;
for(int i = 999999900; i < 1000000100; ++i)
{
f = i;
printf("%d\t%f\n", i, f);
}
return 0;
}
999999900 999999872.000000
999999901 999999872.000000
999999902 999999872.000000
999999903 999999872.000000
999999904 999999872.000000
999999905 999999936.000000
999999906 999999936.000000
999999907 999999936.000000
...
[some lines omitted]
...
999999967 999999936.000000
999999968 1000000000.000000
999999969 1000000000.000000
999999970 1000000000.000000
999999971 1000000000.000000
999999972 1000000000.000000
...
[some lines omitted]
...
1000000028 1000000000.000000
1000000029 1000000000.000000
1000000030 1000000000.000000
1000000031 1000000000.000000
1000000032 1000000000.000000
1000000033 1000000064.000000
1000000034 1000000064.000000
1000000035 1000000064.000000
1000000036 1000000064.000000
1000000037 1000000064.000000
1000000038 1000000064.000000
1000000039 1000000064.000000
1000000040 1000000064.000000
1000000041 1000000064.000000
1000000042 1000000064.000000
1000000043 1000000064.000000https://stackoverflow.com/questions/13119292
复制相似问题