Keine Übereinstimmung der orthografischen Einheitenübersetzung im Raster (z. B. 64 Pixel werden falsch übersetzt)

14

Ich suche einen Einblick in ein kleines Problem mit Einheitenübersetzungen in einem Raster.

Update und gelöst

Ich habe mein eigenes Problem gelöst. Siehe unten für Details. Alles in diesem Teil des Beitrags stellte sich als richtig heraus. Wenn überhaupt, kann es als Miniatur-Tutorial / Beispiel / Hilfe für die nächste Person dienen.

Installieren

  • FBO, VAO, VBO
  • 512x448 Fenster
  • 64x64 Raster
  • gl_Position = projection * world * position;
  • projectiondefiniert durch ortho(-w/2.0f, w/2.0f, -h/2.0f, h/2.0f);Dies ist eine orthogonale Projektionsfunktion des Lehrbuchs.
  • world wird durch eine feste Kameraposition bei (0, 0) definiert
  • position wird durch die Position des Sprites definiert.

Problem

In der Abbildung unten (1: 1-Skalierung) beträgt der Rasterabstand 64 x 64, und ich zeichne die Einheit mit (64, 64). Die Einheit zeichnet jedoch ungefähr ~ 10 Pixel in der falschen Position. Ich habe versucht, einheitliche Fensterabmessungen zu erzielen, um Verzerrungen der Pixelgröße zu vermeiden, aber jetzt bin ich ein bisschen verloren, wenn ich eine 1: 1-Projektion von Pixel-zu-Welt-Einheiten bereitstelle. Wie auch immer, hier sind einige kurze Bilder, die das Problem lösen sollen.

64x64 Kacheln in einem 512x448 Fenster

Ich habe mich entschlossen, ein paar Sprites mit 64-fachen Offsets auszustatten.

64 Offsets überlagert

Als dies unangebracht schien, ging ich umher und machte den Basisfall von 1 Einheit. Welches schien wie erwartet in einer Reihe zu stehen. Das Gelb zeigt einen Unterschied von 1px in der Bewegung.

Grundgehäuse von 1 Einheit

Was ich möchte

Wenn Sie sich im Idealfall in eine beliebige Richtung bewegen, werden mit 64 Einheiten die folgenden (überlagerten Einheiten) ausgegeben:

Gewünschte Ausgabe

Eckpunkte

Es scheint, dass die Scheitelpunkte, die in den Scheitelpunkt-Shader gehen, korrekt sind. In Bezug auf das erste Bild sehen die Daten im VBO beispielsweise folgendermaßen aus:

      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

Der Vollständigkeit halber ist hier die tatsächliche Anordnung, die den obigen Bewegungen entspricht:

      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.

Projektionsmatrix

Die Projektionsmatrix für das 512x448-Fenster sieht folgendermaßen aus:

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

und ist mit einer orthogonalen Projektionsfunktion aufgebaut:

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;
}

Weltbild-Matrix

Die Position der Kamera ist nur eine Translationsmatrix, die ich in diesem Fall nur um -w / 2 und -h / 2 versetzt habe, um null in Bezug auf die Mitte zu sein.

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

Lösungen, die ich versucht habe

  1. player.moveRight()würde sich mit dem in die Gleichung einbezogenen Seitenverhältnis um eine Einheit bewegen. Also: gridWidth = 64 / 1.14f. Die Bewegung passte nicht in das Raster.

  2. Erzwang ein 512x512 Fenster mit einer passenden orthogonalen Projektion.

  3. Versuchte verschiedene magische Zahlen und versuchte, Korrelationen zwischen den beiden zu ziehen.

Trotzdem muss ich nur glauben, dass ich meine eigentliche Projektion vermassele. Daher suche ich nach Erkenntnissen zur Beibehaltung der 1: 1-Projektion von Pixel zu Welt.

Justin Van Horne
quelle
5
Gut konstruierte Frage, aber vielleicht können wir Ihre Projektions- und Weltmatrizen sehen. Sie haben sie oben erwähnt, aber ihren Inhalt nicht angegeben. Das Problem wird mit einer dieser Matrizen sein.
Ken
@ Ken Kein Problem. Ich habe meine Projektions- und Weltraummatrizen hinzugefügt. Ich habe auch meine gewünschte Ausgabe und meine eigenen Versuche zum Problem aufgenommen.
Justin Van Horne
Sie Matrizen gut aussehen (ich sie im Vergleich diejenigen , produziert von glOrtho und glTranslate Grapsing an Strohhalme hier, aber opengl erwartet seine Matrizen in Spaltenhauptordnung angeordnet werden Sie das gleiche zu tun.?
Ken
Hm, sie werden spaltenweise in größerer Reihenfolge gelagert.
Justin Van Horne

Antworten:

5

Ich habe mein eigenes Problem gelöst - und anstatt es nur als einfache Erklärung abzublasen, möchte ich die Schritte beschreiben, die ich unternommen habe, um das Problem zu beheben. Ich habe ausgelassen, dass ich einen einzelnen FBO für Spezialeffekte verwendet habe.

Erstens stellt sich heraus, dass alles, was oben steht, tatsächlich korrekt ist und ein Schritt, den ich ausgelassen habe, das Problem war.

  • Ich habe meine orthogonalen Matrizen durchgehend überprüft.
  • Überprüfte die Bytereihenfolge von allem.
  • Erstellt eine quadratische Textur. <- Hier ist die Magie
  • Als ich eine quadratische Textur erstellte, bemerkte ich, dass es sich nicht um ein Quadrat auf dem Bildschirm handelte, sondern um ein Quadrat im Vertex-Shader.
  • Dies war mein erster Hinweis darauf, dass etwas nicht stimmte. Die Dimensionen meiner Texturen auf dem Bildschirm stimmten nicht mit den Dimensionen überein, die zum Vertex-Shader geleitet wurden.
  • Ich habe vergessen, dass ich einen FBO verwendet habe (hier kommt die Dummheit).
  • Die FBO-Texturgröße stimmte aus irgendeinem dummen Grund nicht mit der Texturgröße meines Ansichtsfensters überein.
  • Deaktiviert den FBO und die Ergebnisse stimmen überein.
  • Die Logik beim Definieren meiner Texturgröße und Wah-Lah wurde korrigiert.

Dummheit

Es tut mir leid, wenn dies jemandes Zeit in Anspruch nahm. Ich werde die Frage als gute Maßnahme für jeden belassen, der möglicherweise auf dasselbe Problem stößt, ohne es zu wissen.

Justin Van Horne
quelle