Saya harus menulis rasterizer 3d perangkat lunak saya sendiri, dan sejauh ini saya dapat memproyeksikan model 3d saya yang terbuat dari segitiga ke dalam ruang 2d:
Saya memutar, menerjemahkan, dan memproyeksikan poin saya untuk mendapatkan representasi ruang 2d dari setiap segitiga. Kemudian, saya mengambil 3 titik segitiga dan saya menerapkan algoritma scanline (menggunakan interpolasi linier) untuk menemukan semua titik [x] [y] di sepanjang tepi (kiri dan kanan) dari segitiga, sehingga saya dapat memindai segitiga secara horizontal, baris demi baris, dan isi dengan piksel.
Ini bekerja. Kecuali saya juga harus menerapkan z-buffering. Ini berarti bahwa dengan mengetahui koordinat z yang diputar & diterjemahkan dari 3 simpul segitiga, saya harus menginterpolasi koordinat z untuk semua titik lain yang saya temukan dengan algoritma garis pemindaian saya.
Konsepnya tampak cukup jelas, saya pertama kali menemukan Za dan Zb dengan perhitungan berikut:
var Z_Slope = (bottom_point_z - top_point_z) / (bottom_point_y - top_point_y);
var Za = top_point_z + ((current_point_y - top_point_y) * Z_Slope);
Kemudian untuk setiap Zp saya melakukan interpolasi yang sama secara horizontal:
var Z_Slope = (right_z - left_z) / (right_x - left_x);
var Zp = left_z + ((current_point_x - left_x) * Z_Slope);
Dan jika z saat ini lebih dekat ke penampil daripada z sebelumnya pada indeks itu MAKA tulis warna ke buffer warna DAN tulis z baru ke buffer z. (sistem koordinat saya adalah x: kiri -> kanan; y: atas -> bawah; z: wajah Anda -> layar komputer;)
Masalahnya adalah, rusak. Proyeknya ada di sini dan jika Anda memilih tombol radio "Z-Buffered", Anda akan melihat hasilnya ... ( perhatikan bahwa saya menggunakan algoritma pelukis (-hanya- untuk menggambar bingkai gambar) dalam mode "Z-Buffered" untuk keperluan debugging )
PS: Saya sudah baca di sini bahwa Anda harus mengubah z menjadi timbal balik mereka (artinya z = 1/z
) sebelum Anda melakukan interpolasi. Saya mencobanya, dan tampaknya tidak ada perubahan. Apa yang saya lewatkan? (adakah yang bisa menjelaskan, tepatnya di mana Anda harus mengubah z menjadi 1 / z dan di mana (jika) untuk mengembalikannya?)
[EDIT] Berikut beberapa data tentang nilai z maksimum dan minimum yang saya dapatkan:
max z: 1; min z: -1; //<-- obvious, original z of the vertices of the triangles
max z: 7.197753398761272; min z: 3.791703256899924; //<-- z of the points that were drawn to screen (you know, after rotation, translation), by the scanline with zbuffer, gotten with interpolation but not 1/z.
max z: 0.2649908532179404; min z: 0.13849507306889008;//<-- same as above except I interpolated 1/z instead of z.
//yes, I am aware that changing z to 1/z means flipping the comparison in the zBuffer check. otherwise nothing gets drawn.
Sebelum saya melakukan debugging yang susah payah, dapatkah seseorang mengonfirmasi bahwa konsep saya sejauh ini benar?
[EDIT2]
Saya telah memecahkan z-buffering. Ternyata, urutan gambar tidak kacau sama sekali. Koordinat z dihitung dengan benar.
Masalahnya adalah, dalam upaya meningkatkan frame rate saya, saya menggambar kotak 4px / 4px, setiap piksel ke-4, bukan piksel aktual di layar. Jadi saya menggambar 16px per piksel, tetapi memeriksa z buffer hanya untuk satu dari mereka. Aku payah.
TL / DR: Pertanyaannya masih tetap: Bagaimana / mengapa / kapan Anda harus menggunakan kebalikan dari Z (seperti pada 1 / z) alih-alih Z? Karena saat ini, semuanya berjalan baik. (tidak ada perbedaan nyata).