Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Math OpenGL Far Plane提供了非常大的值剪辑一切_Math_Opengl_Perspective - Fatal编程技术网

Math OpenGL Far Plane提供了非常大的值剪辑一切

Math OpenGL Far Plane提供了非常大的值剪辑一切,math,opengl,perspective,Math,Opengl,Perspective,我发现如果我将透视矩阵的远平面距离定义为100000000,那么该范围内的所有对象都会被剪裁。100000000的范围可以正常工作。 有人能解释吗?我的意思是,它仍然不接近浮点数的最大范围。还是我错了?为了计算透视图,我使用GLM库。无固定管线 更新:(JAVA) 透视矩阵计算: public static Mat4 perspective(float fovy, float aspect, float zNear, float zFar) { float range = (float

我发现如果我将透视矩阵的远平面距离定义为
100000000
,那么该范围内的所有对象都会被剪裁。
100000000
的范围可以正常工作。 有人能解释吗?我的意思是,它仍然不接近浮点数的最大范围。还是我错了?为了计算透视图,我使用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;
  }

您看到的是一个舍入问题,因为浮点数的精度非常有限

虽然浮点数的范围很大(对于大多数实际应用来说是“无限的”),但它们的精度有限,远远低于相同大小的整数。单精度(32位)
浮点
可以表示略多于7位的十进制数字。您可以有非常小或非常大(比您想象的更小或更大)的数字,但它们仍然只有7.22个有效的十进制数字

在999999900和1000000100之间,唯一可以表示为单精度浮点的数字是:9999999872、999999936、1000000000和1000000064。您可以通过计算
for
循环中的整数变量,转换为
float
变量,并打印它来轻松验证这一点

这意味着,例如999999950和999999951与999999999是完全相同的数字,因此999999950可能会被剪裁,尽管它“明显”位于剪裁平面前面

编辑:

带有输出的小演示程序:

#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.000000
#包括
int main()
{
浮动f=0.0f;
对于(整数i=99999900;i<1000000100;+i)
{
f=i;
printf(“%d\t%f\n”,i,f);
}
返回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
...
[省略了一些行]
...
999999967       999999936.000000
999999968       1000000000.000000
999999969       1000000000.000000
999999970       1000000000.000000
999999971       1000000000.000000
999999972       1000000000.000000
...
[省略了一些行]
...
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.000000

我不确定我是否理解这个问题,但单精度浮点可以表示略多于7位的十进制数字。您的数字有10位数字,因此只有最后3位数字不同的坐标是“相同的”。因此,999999950可能会被剪掉。这就是你想知道的吗?听起来像是个取整问题之类的。当然,它不跨越浮点范围(它甚至不跨越32位int范围)。但是除以这么大的数字可能会把所有的值都变成0。同样,当将一些非常小的数字添加到这个大的数字时(如在矩阵计算期间完成的
near+far
near-far
),该数字很可能保持不变。需要特别分析这对矩阵计算的影响。谢谢你的回答。但是你上面的一个家伙说了相反的话。那么1.000.000.000在这种情况下是浮动限制吗?@MichaelIV 100000000适合浮动范围(以一个难以想象的大值结束),但它很可能无法精确表示(如Damon所说)在计算中将如此大的数字与非常小的数字(如
near
很可能是)相结合将导致重大的舍入问题(如我所说)。深入研究浮点计算理论和舍入问题,以获得更多的见解。