Szukam wglądu w mały problem z tłumaczeniami jednostkowymi na siatce.
Aktualizacja i rozwiązanie
Rozwiązałem własny problem. Szczegóły poniżej. Wszystko w tej części postu okazało się prawidłowe. Jeśli tak, może działać jako miniaturowy samouczek / przykład / pomoc dla następnej osoby.
Ustawiać
- FBO, VAO, VBO
- Okno 512x448
- Siatka 64x64
gl_Position = projection * world * position;
projection
jest zdefiniowany przezortho(-w/2.0f, w/2.0f, -h/2.0f, h/2.0f);
To jest podręcznikowa funkcja projekcji ortogonalnej.world
jest zdefiniowany przez stałą pozycję kamery w (0, 0)position
jest zdefiniowany przez pozycję duszka.
Problem
Na poniższym zrzucie ekranu (skalowanie 1: 1) odstępy siatki wynoszą 64 x 64, a ja rysuję jednostkę w (64, 64), jednak jednostka rysuje w przybliżeniu ~ 10px w niewłaściwej pozycji. Próbowałem ujednolicić wymiary okna, aby zapobiec zniekształceniu rozmiaru piksela, ale teraz jestem trochę zagubiony we właściwy sposób, zapewniając projekcję 1: 1 piksel na jednostkę świata. Tak czy inaczej, oto kilka krótkich zdjęć, które mogą pomóc w rozwiązaniu problemu.
Zdecydowałem się narzucić kilka duszków według tego, co silnik uważa za przesunięcie 64x.
Kiedy wydawało się to nie na miejscu, poszedłem i zrobiłem podstawową skrzynkę z 1 jednostką. Które wydawało się zgodne z oczekiwaniami. Żółty pokazuje różnicę 1px w ruchu.
Czego chcę
Idealnie poruszając się w dowolnym kierunku 64 jednostki wygenerowałyby następujące (jednostki nałożone):
Wierzchołki
Wydaje się, że wierzchołki wchodzące w moduł cieniujący wierzchołki są poprawne. Na przykład w odniesieniu do pierwszego obrazu dane w VBO wyglądają tak:
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
Dla kompletności tutaj jest rzeczywista tablica odpowiadająca powyższym ruchom:
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.
Matryca projekcyjna
Macierz projekcji dla okna 512x448 wygląda następująco:
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
i jest zbudowany z podręcznej funkcji projekcji ortogonalnej:
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;
}
Matryca światopoglądu
Pozycja kamery jest tylko macierzą translacji, która w tym przypadku po prostu przesunęła się o -w / 2 i -h / 2, aby była równa zero względem środka.
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
Rozwiązania, które próbowałem
player.moveRight()
przesuwałby się o 1 jednostkę przy uwzględnionym współczynniku kształtu w równaniu. Tak:gridWidth = 64 / 1.14f
. Ruch nie mieścił się w siatce.Wymuszono okno 512x512 z pasującym rzutem ortogonalnym.
Próbowałem różnych magicznych liczb i próbowałem narysować korelacje między nimi.
Powiedziawszy to, pozostało mi tylko wierzyć, że wzmacniam moją rzeczywistą projekcję. Tak więc szukam jakiegokolwiek wglądu w utrzymywanie projekcji piksel na jednostkę świata 1: 1.