Saya memutar mesin 3D saya sendiri, dalam JavaScript, dan hanya menggunakan gambar kanvas, tanpa WebGL. Ini adalah klon Minecraft lainnya; Saya suka kotak, jangan menilai saya.
Sejauh ini, semuanya bekerja dengan luar biasa, kecuali satu hal: dalam 3D, ketika beberapa simpul berada di belakang pesawat kliping dekat, proyeksi mereka di layar menjadi aneh (dengan asumsi simpul lain yang digunakan untuk melacak pesawat ada di depan).
Saya mencoba memotong titik-titik ini tetapi kemudian saya bisa melihat melalui permukaan yang menggunakan simpul ini. Di WebGL / OpenGL kartu grafis menangani titik-titik ini dan pesawat diberikan dengan benar, tetapi saya tidak memiliki akses ke perangkat keras jadi saya harus kode ini sendiri.
Saya tidak begitu yakin apa yang harus saya lakukan, saat ini hal terakhir yang terlintas dalam pikiran saya adalah membalikkan proyeksi poin di belakang pesawat dekat kliping pemain, yang tampaknya logis karena saya harus memproyeksikan titik ke layar yang ada di depan. dari simpul.
Inilah pikiran saya:
Berikut adalah beberapa gambar untuk menggambarkan apa yang terjadi:
Dari kejauhan kotak biru tampak sempurna.
Ketika beberapa simpul berada di belakang bidang kliping dekat pemain, saya melakukan proyeksi terbalik, tetapi tidak terlihat benar:
focalLength *= -1;
2d.x = x*focalLength/z;
2d.y = y*focalLength/z;
Perhatikan bahwa kotak abu-abu di belakang sepenuhnya dihapus karena semua simpul yang digunakan untuk menggambar wajahnya ada di belakang pemain.
Inilah yang terjadi ketika melihat ke atas atau ke bawah.
Saya tidak tahu bagaimana membuat matematika di balik ini, saya berharap seseorang telah mengalami masalah yang sama dan dapat membantu saya.
sumber
lineTo(x,y)
fungsinya masih bisa dipanggil, hanya saja saya tidak tahu bagaimana perilakunya ... itu dimensi yang aneh, saya setuju.Jawaban:
Tujuan dari pesawat kliping dekat adalah bahwa itu adalah pesawat kliping . Segitiga yang berada di luar bidang kliping terpotong : dipotong-potong sehingga setiap bagian yang tersisa berada di dalam wilayah kliping.
Anda dapat mencoba untuk mengabaikan klip dekat jika Anda mau. Memang OpenGL dan D3D memiliki cara mematikan dekat kliping pesawat sama sekali (meskipun buffer kedalaman masih memiliki nilai dekat minimum). Masalahnya bukan klip dekat.
Masalahnya adalah dengan simpul yang ada di belakang kamera.
Anda tidak dapat membuat segitiga yang ada di belakang kamera. Bukan dengan proyeksi perspektif. Segitiga semacam itu tidak masuk akal di bawah matematika di balik proyeksi perspektif. Selain itu, mereka juga berada di luar frustrasi.
Mematikan kliping dekat mengubah frustum menjadi piramida. Alasan piramida berhenti pada titik tersebut adalah karena titik di atas piramida berada di belakang keempat sisi piramida. Jadi setiap titik di belakang kamera (ujung piramida) berada di atas, di bawah, ke kiri, dan ke kanan wilayah layar yang terlihat. Semua di waktu yang sama.
Seperti yang saya katakan: simpul di bawah proyeksi perspektif yang ada di belakang kamera tidak masuk akal.
Anda harus menerapkan kliping. Anda harus mendeteksi ketika ada simpul segitiga, di ruang klip ( sebelum pembagian perspektif) di belakang kamera. Jika ya, maka Anda harus memotong segitiga itu, hanya menghasilkan segitiga yang ada di depan kamera.
Ini bukan proses yang sederhana. Ini akan melibatkan matematika yang hanya masuk akal jika Anda memiliki pemahaman penuh tentang sistem koordinat yang homogen. Atau, Anda bisa langsung menyisihkan segitiga jika ada simpul di belakang kamera.
sumber
Jika bagian dari segitiga di belakang bidang dekat dapatkah Anda melakukan pemeriksaan per-pixel untuk melihat apakah posisi piksel berada di belakang bidang kliping?
Anda mungkin memperlakukan pesawat dekat seperti pesawat kliping lainnya. Misalnya pesawat kliping digunakan untuk hal-hal seperti pesawat air (untuk refleksi dan refraksi). Saya akan berpikir bahwa pesawat kliping ini akan bekerja seperti pesawat kliping dekat, dan klip pada basis per-pixel.
Saya tahu bagaimana menangani pesawat kliping di HLSL dengan DirectX, tetapi implementasinya bisa menjadi hak milik. Jika Anda bisa mendapatkan info untuk itu mungkin akan membantu.
Selain itu, berikut ini tautan yang mungkin membantu Anda: http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter42.html
sumber