5

透視行列の遠面距離を に定義すると1,000,000,000、その範囲内のすべてのオブジェクトが切り取られることがわかりました。正常に動作する範囲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;
  }
4

1 に答える 1

8

表示されているのは、浮動小数点数の精度が非常に限られているため、丸めの問題です。

浮動小数点数の範囲は非常に広い (ほとんどの実用的なアプリケーションでは「無限」) ですが、同じサイズの整数よりもはるかに低い精度に制限されています。単精度 (32 ビット)floatは、10 進数で 7 桁強を表すことができます。非常に小さいまたは大きい (想像できるよりも小さいまたは大きい) 数値を使用できますが、有効な 10 進数は 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.000000
于 2012-10-29T10:56:01.063 に答える