グリッド上での単位変換に関する小さな問題についての洞察を探しています。
更新および解決済み
私は自分の問題を解決しました。詳細は以下をご覧ください。投稿のこの部分のすべてが正しいことが判明しました。どちらかといえば、次の人のためのミニチュアチュートリアル/例/ヘルプとして機能することができます。
セットアップ
- 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ピクセルから世界単位への投影を行う際に、適切な方法で少し迷っています。とにかく、ここに問題を支援するためのいくつかの簡単な画像があります。
私は、エンジンが64xオフセットであると信じているスプライトの束をスーパーインポーズすることにしました。
これがふさわしくないように思えたとき、私はあちこちに行き、1ユニットのベースケースをしました。予想通りに並んでいたようです。黄色は、動きの1pxの違いを示しています。
私が欲しいもの
理想的には、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
私が試みた解決策
player.moveRight()
アスペクト比を方程式に含めて1単位移動します。だから:gridWidth = 64 / 1.14f
。動きがグリッド内に収まりませんでした。一致する正射影で512x512ウィンドウを強制しました。
さまざまな魔法の数字を試して、2つの間に相関関係を引き出そうとしました。
そうは言っても、私が信じるのは、実際の予測を変更することだけです。そこで、1対1ピクセルから世界単位への投影を維持するための洞察を探しています。