Saya belajar beberapa dasar-dasar OpenGL tapi saya bertanya-tanya mengapa ada panggilan glNormal
untuk mengatur simpul normal.
Jika saya membuat segitiga sederhana seperti ini:
glBegin(GL_TRIANGLES);
glVertex3f(0,0,0);
glVertex3f(1,0,0);
glVertex3f(0,1,0);
glEnd();
Haruskah normals didefinisikan secara implisit oleh tipe geometri primitif? Jika saya tidak menetapkan normal apakah OpenGL akan menghitungnya?
Jawaban:
Memanggil
glNormal
beberapa kali antaraglBegin/End
memungkinkan Anda untuk mengatur normal per simpul bukan primitif.Untuk mesh yang lebih kompleks yang terdiri dari beberapa segitiga Anda ingin normal pada satu titik bergantung pada segitiga lain dari geometri sekitarnya dan bukan hanya normal dari segitiga yang dimilikinya.
Berikut adalah contoh geometri yang sama dengan:
(0,0,1)
):Model naungan default (
GL_SMOOTH
) menyebabkan normals dari simpul wajah diinterpolasi melintasi wajah. Untuk per-vertex normals ini menghasilkan bulatan berbayang halus, tetapi untuk per-face normals Anda berakhir dengan tampilan segi karakteristik.sumber
Tidak, GL tidak menghitung norma untuk Anda. Tidak tahu apa yang seharusnya. Primitif Anda tidak berarti apa pun di luar rasterisasi (dan beberapa tempat lain). GL tidak tahu wajah mana (segitiga) yang berbagi titik (menghitung ini pada saat runtime sangat mahal tanpa menggunakan struktur data yang berbeda).
Anda perlu memproses "sup segitiga" mesh untuk menemukan simpul umum dan menghitung normalnya. Ini harus dilakukan sebelum permainan berjalan untuk kecepatan.
Ada juga kasus-kasus seperti tepi keras di mana secara geometris ada simpul bersama di sudut, tetapi Anda ingin normalnya terpisah sehingga menyala dengan benar. Dalam model rendering GL / D3D, Anda memerlukan dua simpul terpisah (pada posisi yang sama) untuk ini, masing-masing dengan normal yang terpisah.
Anda juga memerlukan semua ini untuk pemetaan tekstur dan UV.
sumber
Jawaban singkatnya adalah Anda tidak harus menetapkan normal sama sekali. Vektor normal hanya digunakan jika Anda melakukan pencahayaan OpenGL (atau mungkin beberapa perhitungan lain yang mungkin bergantung pada mereka), tetapi jika itu tidak berlaku untuk Anda (atau jika Anda menggunakan beberapa metode lain untuk melakukan pencahayaan, mis. Peta cahaya ) maka Anda dapat dengan senang hati menghilangkan semua panggilan glNormal.
Jadi mari kita asumsikan bahwa Anda melakukan sesuatu di mana menentukan glNormal masuk akal dan melihatnya lagi.
glNormal dapat ditentukan per primitif atau per-verteks. Dengan normals per-primitif, semua artinya adalah semua normals untuk setiap simpul di wajah primitif dalam arah yang sama. Kadang-kadang ini yang Anda inginkan tetapi terkadang tidak - di mana normalnya per-simpul berguna adalah bahwa mereka memungkinkan setiap simpul memiliki wajah sendiri.
Ambil contoh klasik bola. Jika setiap segitiga dalam bola memiliki normal yang sama maka hasil akhirnya akan cukup faceted. Mungkin itu bukan yang Anda inginkan, Anda justru menginginkan shading yang halus. Jadi yang Anda lakukan adalah rata-rata normals untuk setiap segitiga yang berbagi titik umum, dan mendapatkan hasil yang diarsir halus.
sumber
Contoh minimal yang menggambarkan beberapa detail tentang bagaimana
glNormal
bekerja dengan petir yang menyebar.Komentar
display
fungsi menjelaskan arti setiap segitiga.Teori
Dalam OpenGL setiap vertex memiliki vektor normal yang terkait.
Vektor normal menentukan seberapa terang verteks itu, yang kemudian digunakan untuk menentukan seberapa terang segitiga itu.
Saat permukaan tegak lurus terhadap cahaya, permukaan lebih terang dari permukaan paralel.
glNormal
mengatur vektor normal saat ini, yang digunakan untuk semua simpul berikut.Nilai awal untuk normal sebelum kita semua
glNormal
adalah0,0,1
.Vektor normal harus memiliki norma 1, atau warna berubah!
glScale
juga mengubah panjang normals!glEnable(GL_NORMALIZE);
membuat OpenGL secara otomatis mengatur norma mereka ke 1 untuk kita. GIF ini menggambarkan hal itu dengan indah.Bibliografi:
sumber
Anda memerlukan glNormal untuk mengimplementasikan beberapa fitur yang tergantung pada coder. Sebagai contoh, Anda mungkin ingin membuat data normal mempertahankan tepi yang sulit.
sumber