5

私は宇宙探査アプリケーションを書いています。単位は光年に決め、星間の距離を正確にモデル化しました。いじり回したり、多くの骨の折れる作業 (主にロープの学習) を行った後、宇宙を横断する宇宙船の視点からカメラが正しく機能するようになりました。

最初は、惑星オブジェクトに取り組むまで、gluPerspective () の zNear パラメーターに注意を払いませんでした。私の目盛りは光年単位なので、zNear が 1.0f であるため、そのような天体を見ることができないことにすぐに気付きました。実験の後、私はこれらの数字にたどり着きました:

#define POV 45
#define zNear 0.0000001f
#define zFar 100000000.0f
gluPerspective (POV, WinWidth/WinHeight, zNear ,zFar);

これは、太陽系 (位置 0,0,0) を巡航し、惑星の近くまで移動することができたという点で非常にうまく機能します。ただし、他のシステム (位置 0,0,0 ではない) は、オブジェクトが異常な方法でカメラから遠ざかるため、通過するのがはるかに困難でした。

しかし、宇宙をクルージングしているときに、奇妙な視覚的な不具合が発生し始めていることに気付きました。Y 方向に 180 度スイングすると、後ろのオブジェクトが「ラップアラウンド」して前方に表示され、元の場所にも表示されます。そのため、宇宙をワープするとき、ほとんどの星は正しく視差しますが、一部の星は現れて反対方向に移動します (控えめに言っても邪魔です)。

zNear を 0.1f に変更すると、これらのすべての不具合が即座に修正されます (ただし、太陽系のオブジェクトも解決されません)。だから私は立ち往生しています。また、glFrustum を使用してみましたが、まったく同じ結果が得られます。

私は以下を使用して世界を表示します。

glTranslatef(pos_x, pos_y, pos_z);

関連するカメラ コードを使用して、必要に応じて向きを合わせます。カメラ機能を無効にしても何も変わりません。gluLookAt() も試してみましたが、同じ結果が得られます。

極端な zNear / zFar 値が使用されている場合、gluPerspective() には制限がありますか? 射程距離を縮めようとしたが無駄だった。すべてを拡大し、より大きな zNear 値を使用することで、世界の単位を光年からキロメートルに変更しました。ヘルプ!

4

3 に答える 3

5

問題は、同時に多くのことを解決したいということです。太陽系のスケールで物事を見たいと思っていますが、半銀河のスケールも持っています. それは単に不可能です。リアルタイムレンダラーではありません。

浮動小数点の精度はそれほど多くありません。そして、zNear が非常に近いため、基本的に、カメラから約 0.0001 以上離れたものについて深度バッファーを破壊しました。

あなたがする必要があるのは、距離に基づいて物事を描くことです。近くのオブジェクト (太陽系のスケール内) は、1 つの深度範囲 (0 から 0.8 など) を使用して、1 つの透視マトリックスで描画されます。次に、より遠くのオブジェクトが、異なる遠近マトリックスと異なる深度範囲 (0.8 ~ 1) で描画されます。これが、この作業を行う唯一の方法です。

また、CPU 上のオブジェクトの行列を倍精度演算で計算し、それらを OpenGL で使用するために単精度に戻す必要がある場合もあります。

于 2011-09-07T18:35:20.020 に答える
3

OpenGLは、zFarよりもカメラから遠く、またはzNearよりもカメラに近いものを描画してはなりません。

ただし、その中間の場合、OpenGLは、あるオブジェクトが別のオブジェクトをブロックしているかどうかを判断するために使用する深度バッファーに格納されている深度値を計算します。残念ながら、デプスバッファの精度は制限されており(通常は16ビットまたは24ビット)、これによるとおよそlog2(zFar / zNear)ビットの精度が失われます。したがって、10 ^ 15(〜50ビットが失われる)のzFar / zNear比は、問題を引き起こすことになります。1つのオプションは、zNearをわずかに増やすことです(可能な場合)。それ以外の場合は、SplitDepthBuffersまたはLogarithmicDepthBuffersを調べる必要があります

于 2011-09-11T03:13:46.360 に答える
1

ニコル・ボーラスはすでに話の一部を話してくれた。もう 1 つは、座標を格納するための構造化された方法について考え始める必要があるということです。各オブジェクトの位置を、それを重力で支配するオブジェクトとの関係で格納し、それらに適切な単位を使用します。

だからあなたは星を持っています。星間の距離は光年で測定されます。恒星は惑星によって周回されています。星系内の距離は、光分から光時の単位で測定されます。惑星は月によって周回されています。惑星系の距離は光秒で測定されます。

このようなスケールを表示するには、複数のパスでレンダリングする必要があります。鱗のあるオブジェクトがツリーを形成します。最初に、離れた枝を近くに並べ替えてから、最初に木の深さをトラバースします。分岐レベルごとに、適切な投影パラメータを使用して、近くから遠くへのクリップ プレーンがレンダリングされるオブジェクトにぴったりと合うようにします。各レベルをレンダリングした後、深度バッファをクリアします。

于 2011-09-07T21:28:22.383 に答える