1

不正確なZ座標を取得しているため、gluUnProjectで問題が発生しています。

関連するプログラムは、基本的に3Dビューアです。ロードされたモデルをクリックして、2点間の距離を取得できるようにする小さな関数を実装しました。

これはコードです:

//  Declare variables for viewport, modelview and projection matrix
int viewport[] = new int[4];
float modelview[] = new float[16];
float projection[] = new float[16];
//  GL y-coordinate position
int realY;
//  Returned [wx, wy, wz, 1] coordinates
float worldCoordinates[] = new float[4];

gl2.glGetIntegerv(GL2.GL_VIEWPORT, viewport, 0);
gl2.glGetFloatv(GL2.GL_MODELVIEW_MATRIX, modelview, 0);
gl2.glGetFloatv(GL2.GL_PROJECTION_MATRIX, projection, 0);

//  Retrive the Y coordinate, note viewport[3] is height of window in pixels
realY = viewport[3] - click.y - 1;

//  Allocate a buffer to store the result
FloatBuffer fb = FloatBuffer.allocate(1);

//  Retrieve the Z coordinate, read a block of pixels from the frame buffer
gl2.glReadPixels(click.x, realY, 1, 1, GL2.GL_DEPTH_COMPONENT, GL2.GL_FLOAT, fb);

System.out.println("Depth: "+fb.get(0));

//  Avoid centering if the click is on nothing
if (fb.get(0) == 1.0f) {
    return null;
}
//  Map window coordinates to object coordinates, retrieve the world coordinates
glu.gluUnProject(click.x, realY, fb.get(0), modelview, 0, projection, 0,
            viewport, 0, worldCoordinates, 0);

ユーザーに垂直な面にある2点間の距離を測定しているときは、すべてが正しく機能します。zがユーザーを指し、yが上を指す、3軸システムをイメージすると、2つのポイントはXY平面上にあります。Zを中心とした回転に関係なく機能します。

ここに画像の説明を入力してください

たとえば、ここで小さな正方形の平面を作成しましたが、2つのポイントは両方とも同じ高さです(1つはラベルによって隠されています)。

世界座標P1:(0.019062456、0.03357359、0.08333321、1)

世界座標P2:(0.025983132、0.028048635、0.08333321、1)

しかし、シーン全体をグローバルX軸上で回転させると、取得されたZ座標は次のように変化します。

ここに画像の説明を入力してください

X座標とY座標は関係ありません。重要なのは、Z座標です。これ以上0.08333321ではありません。

世界座標P1:(0.026863147、0.027185505、0.0831252、1)

世界座標P2:(0.020072304、0.034560144、0.08312501、1)

さらに、グローバルXを回転した後、ズームもポイントのZ座標に影響します。

追伸:私はJOGLを使用しています。ズームインとズームアウトは、平行六面体のグロルトを拡大/縮小することによって実行されます。glReadPixelsによって生成されるZ深度fb.get(0)は、[0、1]に含まれています。

私はどこが間違っていますか?

4

1 に答える 1

1

平面上の点の正確な座標を確認することを期待していますか?あなたはそれをこのように得るつもりはありません。

正方形をレンダリングすると、座標が3Dに変換され、プリミティブがラスター化され(つまり、2Dに変換されて補間され)、画面X、Yおよび(通常は)24ビットの深度値が生成されます。これは精度のかなりの低下です(そしてそれは線形でさえありません)ので、それを読んで変換を反転すると、元の値の近似値しか得られません。

ポリゴンがビュー方向に垂直である場合、補間によって少なくともサーフェス全体で一貫したz値が得られます(変換されたすべてのZ値は同じであるため)。ただし、必ずしも正しいz値になるとは限りません。 。したがって、深度を変更するとエラーが変更され、平面が垂直でない場合は、ポリゴン全体で一貫性が失われます。

深さは基本的に、あまり多くのエラーなしで(そしてそれでも常にではない)描画するには十分ですが、正確なジオメトリを再構築するには十分ではありません。

より良い結果が必要な場合は、実際のモデル空間X、Y、Zをシェーダーを使用して(フロート)FBOにラスタライズし、それを読み戻すことができます。または、ソフトウェアで光線をジオメトリと交差させます。

于 2013-01-09T13:53:08.687 に答える