2012-10-29 3 views
5

私は、透視平面の距離が1,000,000,000であると定義すると、その範囲内のすべてのオブジェクトが切り取られます。 100,000,000の範囲で正常に動作します。 誰でもこれを説明できますか?つまり、それでも浮動小数点の最大値は近似しません。または私はこれに間違っていますか?遠近法を計算するために私はGLMライブラリを使用します。固定されたパイプライン剛性はありません。OpenGL Far Planeが非常に大きな値のクリップをすべて与えた

UPDATE:(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; 
    } 
+2

私は質問を理解してますが、単精度浮動小数点が7桁の上に少しを表現できるわけではありません。あなたの番号は10桁ですので、最後の3桁の座標だけが「同じ」です。したがって、999,999,950がクリップされる可能性があります。それはあなたが不思議なことですか? – Damon

+1

丸めの問題などのような音がします。もちろん、浮動小数点の範囲を超えません(32ビットのint範囲を超えない)。しかし、このような大きな数で割るとすべてが0になる可能性があります。同様に、行列の計算中に「near + far」や「near-far」のようにこの数に非常に小さな数を加えると、変更しないでください。これがマトリックスの計算にどのように影響するかを分析する必要があります。 –

+0

答えをありがとう。しかし、あなたの上の男は、反対を言った。 –

答えて

8

あなたが見ている何が原因浮動小数点数の非常に有限精度に丸め問題です。

浮動小数点数は、(ほとんどの実用的なアプリケーションでは「無限」の)巨大な範囲ですが、精度が限られており、同じサイズの整数の精度をはるかに下回ります。単精度(32ビット)floatは、小数点以下7桁を表すことができます。非常に小さくても大きくても(あなたが想像するよりも小さくても大きくても)、数値は有効ですが、それでも有効な小数は7.22です。

999999900と十億百間単精度floatとして表現数字だけである:999999872、999999936、1000000000、および1000000064.簡単float変数にキャスト、forループの整数変数をカウントすることによってこれを確認することができ、そしてそれを印刷する。

たとえば、999,999,950と999,999,951と999,999,999はまったく同じ数値なので、999,999,950はクリッピングプレーンの前で「明らかに」クリッピングされることがあります。

EDIT:出力と

リトルデモプログラム:

#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 
関連する問題