グリッド上の正投影単位の変換の不一致(たとえば、64ピクセルが正しく変換されない)


14

グリッド上での単位変換に関する小さな問題についての洞察を探しています。

更新および解決済み

私は自分の問題を解決しました。詳細は以下をご覧ください。投稿のこの部分のすべてが正しいことが判明しました。どちらかといえば、次の人のためのミニチュアチュートリアル/例/ヘルプとして機能することができます。

セットアップ

  • FBO、VAO、VBO
  • 512x448ウィンドウ
  • 64x64グリッド
  • gl_Position = projection * world * position;
  • projection定義されるortho(-w/2.0f, w/2.0f, -h/2.0f, h/2.0f);この教科書正射影関数です。
  • world (0、0)の固定カメラ位置によって定義されます
  • position スプライトの位置によって定義されます。

問題

以下のスクリーンショット(1:1スケーリング)では、グリッド間隔は64x64であり、ユニットを(64、64)で描画していますが、ユニットは約10pxを間違った位置に描画します。ピクセルサイズのゆがみを防ぐために均一なウィンドウディメンションを試しましたが、1対1ピクセルから世界単位への投影を行う際に、適切な方法で少し迷っています。とにかく、ここに問題を支援するためのいくつかの簡単な画像があります。

512x448ウィンドウ上の64x64タイル

私は、エンジンが64xオフセットであると信じているスプライトの束をスーパーインポーズすることにしました。

重畳された64オフセット

これがふさわしくないように思えたとき、私はあちこちに行き、1ユニットのベースケースをしました。予想通りに並んでいたようです。黄色は、動きの1pxの違いを示しています。

1ユニットのベースケース

私が欲しいもの

理想的には、64ユニットが任意の方向に移動すると、以下が出力されます(重ね合わせたユニット)。

望ましい出力

頂点

頂点シェーダーに入る頂点が正しいように見えます。たとえば、最初の画像を参照すると、データはVBOで次のようになります。

      x    y           x    y
    ----------------------------    
tl | 0.0  24.0        64.0 24.0
bl | 0.0  0.0    ->   64.0 0.0
tr | 16.0 0.0         80.0 0.0
br | 16.0 24.0        80.0 24.0

完全を期すために、上記の動きに対応する実際の配列を次に示します。

      x     y    z   w   r   g   b   a      s          t
-------------------------------------------------------------
tl | 0.0   23.0 0.0 1.0 0.0 0.0 0.0 1.0 0.14210527 0.62650603 
bl | 0.0   0.0  0.0 1.0 0.0 0.0 0.0 1.0 0.14210527 0.76506025 
tr | 16.0  0.0  0.0 1.0 0.0 0.0 0.0 1.0 0.2263158  0.76506025 
br | 16.0  23.0 0.0 1.0 0.0 0.0 0.0 1.0 0.2263158  0.62650603 
-------------------------------------------------------------
-------------------------------------------------------------
tl | 64.0  24.0 0.0 1.0 0.0 0.0 0.0 1.0 0.0        0.21084337 
bl | 64.0  0.0  0.0 1.0 0.0 0.0 0.0 1.0 0.0        0.3554217 
tr | 80.0  0.0  0.0 1.0 0.0 0.0 0.0 1.0 0.08421053 0.3554217 
br | 80.0  24.0 0.0 1.0 0.0 0.0 0.0 1.0 0.08421053 0.21084337

// side bar: I know that I have unnecessary data with having a z-axis.
//           The engine flips between perspective and orthogonal and I
//           haven't selectively started pruning data.

投影マトリックス

512x448ウィンドウの投影行列は次のようになります。

0.00390625 0.0         0.0  0.0
0.0        0.004464286 0.0  0.0
0.0        0.0        -1.0  0.0
0.0        0.0         0.0  1.0

教科書の正射影関数で構築されます:

ortho(-w/2.0f, w/2.0f, -h/2.0f, h/2.0f);
// explicitly: ortho(-512/2.0f, 512/2.0f, -448/2.0f, 448.0f

ortho(float left, float right, float bottom, float top)
{
    projection.setIdentity();
    projection.m00 = 2.0f / (right - left);
    projection.m11 = 2.0f / (top - bottom);
    projection.m22 = -1;
    projection.m30 = -(right + left) / (right - left);
    projection.m31 = -(top + bottom) / (top - bottom);
    projection.m32 = 0;
}

世界観マトリックス

カメラの位置は、ちょうどこの場合、中心に対して0になるように-w / 2と-h / 2だけオフセットした平行移動行列です。

1.0 0.0 0.0 -256.0
0.0 1.0 0.0 -224.0
0.0 0.0 1.0 0.0
0.0 0.0 0.0 1.0

私が試みた解決策

  1. player.moveRight()アスペクト比を方程式に含めて1単位移動します。だから:gridWidth = 64 / 1.14f。動きがグリッド内に収まりませんでした。

  2. 一致する正射影で512x512ウィンドウを強制しました。

  3. さまざまな魔法の数字を試して、2つの間に相関関係を引き出そうとしました。

そうは言っても、私が信じるのは、実際の予測を変更することだけです。そこで、1対1ピクセルから世界単位への投影を維持するための洞察を探しています。


5
よく構成された質問ですが、あなたの投影と世界のマトリックスを見ることができます。あなたは上記でそれらに言及しましたが、それらの内容は含めませんでした。問題は、これらの行列の1つにあります。
ケン

@Ken問題ありません。投影とワールド空間ビューマトリックスを追加しました。また、目的の出力と問題に対する自分の試みも含めました。
ジャスティンヴァンホーン

。あなたは(私はものはここにストローでglOrthoとglTranslate Grapsingによって生成されますが、列優先順に配列されたとOpenGLはあなたが同じやっている、その行列を期待し、それらを比較して見て良い行列?
ケン・

うーん、それらは列優先順で格納されています。
ジャスティンヴァンホーン

回答:


5

私は自分の問題を解決しました-そして、単純な説明としてそれを吹き飛ばすのではなく、問題をデバッグするために取ったステップを説明したいと思います。特殊効果のために単一のFBOを使用していることは除外しました。

まず、上記のすべてが実際に正しいことが判明し、私が残したステップは問題でした。

  • 直交行列を徹底的に検証しました。
  • すべてのバイトオーダーを検証しました。
  • 正方形のテクスチャを作成しました。<-ここに魔法があります
  • 正方形のテクスチャを作成したとき、スクリーン上の正方形ではなく、頂点シェーダーに入る正方形に気付きました。
  • これは、何かが間違っているという最初の手がかりでした。画面上のテクスチャの寸法は、頂点シェーダーに適用される寸法と一致しませんでした。
  • 私はFBOを使用していたことを忘れていました(ここに愚かさがあります)。
  • FBOテクスチャサイズは、愚かな理由でビューポートテクスチャサイズと一致しませんでした。
  • FBOを無効にし、結果が一致しました。
  • テクスチャサイズとワラを定義するロジックを修正しました。

愚かさ

これが誰かの時間を割いてくれてすみません。私は、問題を知らずに同じ問題にぶつかる可能性のある人のための良い手段として質問を残します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.