Ketidakcocokan terjemahan unit ortografis pada grid (mis. 64 piksel diterjemahkan secara salah)

14

Saya mencari beberapa wawasan tentang masalah kecil dengan terjemahan unit pada kotak.

Perbarui dan Selesaikan

Saya memecahkan masalah saya sendiri. Lihat di bawah untuk detailnya. Semua yang ada di bagian pos ini ternyata benar. Jika ada, itu bisa bertindak sebagai miniatur tutorial / contoh / bantuan untuk orang berikutnya.

Mempersiapkan

  • FBO, VAO, VBO
  • Jendela 512x448
  • Kotak 64x64
  • gl_Position = projection * world * position;
  • projectiondidefinisikan oleh ortho(-w/2.0f, w/2.0f, -h/2.0f, h/2.0f);Ini adalah fungsi proyeksi orthogonal buku teks.
  • world didefinisikan oleh posisi kamera tetap pada (0, 0)
  • position didefinisikan oleh posisi sprite.

Masalah

Pada tangkapan layar di bawah ini (penskalaan 1: 1) penspasian kisi adalah 64x64 dan saya menggambar unit di (64, 64), namun unit menggambar kira-kira ~ 10px di posisi yang salah. Saya sudah mencoba dimensi jendela yang seragam untuk mencegah distorsi pada ukuran piksel, tapi sekarang saya agak bingung dengan cara yang tepat dalam memberikan proyeksi piksel-ke-dunia-unit 1: 1. Bagaimanapun, berikut adalah beberapa gambar cepat untuk membantu dalam masalah ini.

64x64 Ubin pada jendela 512x448

Saya memutuskan untuk memaksakan banyak sprite pada apa yang diyakini mesin adalah offset 64x.

64 offset diberlakukan secara super

Ketika ini tampak tidak pada tempatnya, saya pergi dan mengerjakan base case dari 1 unit. Yang sepertinya berbaris seperti yang diharapkan. Kuning menunjukkan perbedaan 1px dalam gerakan.

Kasing dasar 1 unit

Apa yang saya inginkan

Idealnya bergerak ke segala arah 64 unit akan menghasilkan yang berikut (unit super-dikenakan):

Output yang diinginkan

Sudut

Akan terlihat bahwa simpul masuk ke vertex shader benar. Misalnya, mengacu pada gambar pertama, data terlihat seperti ini di 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

Demi kelengkapan di sini adalah array aktual yang sesuai dengan gerakan di atas:

      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.

Matriks Proyeksi

Matriks proyeksi untuk jendela 512x448 terlihat seperti ini:

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

dan dibangun dengan fungsi proyeksi orthogonal buku teks:

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

Matriks pandangan dunia

Posisi kamera hanyalah matriks terjemahan yang dalam hal ini saya hanya mengimbangi dengan -w / 2 dan -h / 2 menjadi nol relatif terhadap pusat.

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

Solusi yang saya coba

  1. player.moveRight()akan memindahkan 1 unit dengan rasio aspek yang diperhitungkan dalam persamaan. Jadi: gridWidth = 64 / 1.14f. Gerakan tidak pas di dalam grid.

  2. Memaksa jendela 512x512 dengan proyeksi orthogonal yang cocok.

  3. Mencoba berbagai angka ajaib dan mencoba menggambar korelasi antara keduanya.

Dengan mengatakan itu, semua yang tersisa untuk saya percaya adalah bahwa saya meningkatkan proyeksi saya yang sebenarnya. Jadi, saya mencari wawasan apa pun tentang mempertahankan proyeksi 1: 1 pixel-to-world-unit.

Justin Van Horne
sumber
5
Pertanyaan yang dibangun dengan baik, tapi mungkin kita bisa melihat proyeksi & matriks dunia Anda. Anda menyebutkannya di atas, tetapi tidak mencantumkan isinya. Masalahnya akan dengan salah satu dari matriks tersebut.
Ken
@ Ken Tidak ada masalah sama sekali. Saya telah menambahkan proyeksi dan matriks tampilan ruang-dunia saya. Saya juga menyertakan hasil yang saya inginkan dan usaha saya sendiri pada masalahnya.
Justin Van Horne
Matriks Anda terlihat bagus (saya membandingkannya dengan matriks yang diproduksi oleh glOrtho dan glTranslate. Menggerogoti sedotan di sini, tetapi opengl mengharapkan matriksnya disusun dalam urutan kolom-utama, apakah Anda melakukan hal yang sama?
Ken
Hm, mereka sedang disimpan pesanan kolom-utama.
Justin Van Horne

Jawaban:

5

Saya memecahkan masalah saya sendiri - dan alih-alih meledakkannya sebagai penjelasan sederhana, saya ingin menjelaskan langkah-langkah yang saya ambil untuk men-debug masalah tersebut. Saya lupa bahwa saya menggunakan FBO tunggal untuk efek khusus.

Pertama, ternyata semua yang di atas ternyata benar dan langkah yang saya tinggalkan adalah masalahnya.

  • Saya memverifikasi matriks ortogonal saya melalui-dan-melalui.
  • Mengverifikasi urutan byte dari segalanya.
  • Dibuat tekstur persegi. <- Ini sihirnya
  • Ketika saya membuat tekstur persegi, saya perhatikan itu bukan persegi di layar, tetapi persegi masuk ke vertex shader.
  • Ini adalah petunjuk pertama saya bahwa ada sesuatu yang salah. Dimensi tekstur saya di layar tidak cocok dengan dimensi yang menuju vertex shader.
  • Saya lupa bahwa saya menggunakan FBO (inilah kebodohannya).
  • Ukuran tekstur FBO tidak cocok dengan ukuran tekstur viewport saya karena alasan bodoh apa pun.
  • Menonaktifkan FBO dan hasilnya cocok.
  • Memperbaiki logika dengan menentukan ukuran dan wah-lah tekstur saya.

Konyol

Saya minta maaf jika ini menyita waktu siapa pun. Saya akan meninggalkan pertanyaan sebagai ukuran yang baik bagi siapa saja yang mungkin mengalami masalah yang sama tanpa menyadarinya.

Justin Van Horne
sumber