Saya memiliki kelas yang menghasilkan bentuk 3D berdasarkan input dari kode panggilan. Input adalah hal-hal seperti panjang, kedalaman, busur, dll. Kode saya menghasilkan geometri dengan sempurna, namun saya mengalami kesulitan ketika menghitung normals permukaan. Saat dinyalakan, bentuk saya memiliki pewarnaan / tekstur yang sangat aneh dari permukaan normal yang salah yang sedang dihitung. Dari semua penelitian saya, saya yakin matematika saya benar, sepertinya ada yang salah dengan teknik atau metode saya.
Pada level yang tinggi, bagaimana cara menghitung secara normal permukaan normal untuk bentuk yang dihasilkan? Saya menggunakan Swift / SceneKit di iOS untuk kode saya tetapi jawaban umum baik-baik saja.
Saya memiliki dua array yang mewakili bentuk saya. Salah satunya adalah array titik 3D yang mewakili simpul yang membentuk bentuk. Array lain adalah daftar indeks dari array pertama yang memetakan simpul menjadi segitiga. Saya perlu mengambil data itu dan menghasilkan array ke-3 yang merupakan kumpulan normals permukaan yang membantu dalam pencahayaan bentuk. (lihat SCNGeometrySourceSemanticNormal
di SceneKit` )
Daftar simpul dan indeks selalu berbeda tergantung pada input ke kelas jadi saya tidak bisa pra-menghitung atau hard code permukaan normal.
Jawaban:
Anda tidak ingin hasil yang sepenuhnya mulus. Sementara metode yang dikomentari oleh Nathan Reed: "Hitung setiap titik untuk menghadapi normal, jumlah mereka, jumlah normalisasi", umumnya bekerja kadang-kadang gagal secara spektakuler. Tapi itu tidak penting di sini, kita bisa menggunakan metode itu dengan menambahkan klausa penolakan untuk itu.
Dalam hal ini Anda hanya ingin bagian-bagian tertentu tidak dihaluskan terhadap bagian-bagian tertentu lainnya. Anda ingin tepi keras selektif. Jadi misalnya flat bagian atas dan bawah terpisah membentuk strip segitiga di samping, seperti halnya setiap area datar.
Gambar 1 : Hasil yang Anda inginkan.
Akibatnya Anda hanya ingin rata-rata simpul dari daerah melengkung semua orang lain dapat menggunakan normal mereka mendapatkan bentuk segitiga mereka sendiri. Jadi Anda lebih baik memikirkan jala sebagai 9 wilayah terpisah yang ditangani tanpa yang lain.
Gambar 2 : Gambar menunjukkan struktur mesh dan normals.
Anda tentu dapat secara otomatis menyimpulkan ini dengan tidak termasuk normals yang berada di luar sudut tertentu dari vertex primer normal. Kodesemu:
Itu bekerja, tetapi Anda bisa menghindari semua ini pada waktu pembuatan karena Anda memahami bahwa pesawat yang terpisah bekerja secara berbeda. Jadi hanya sisi melengkung yang membutuhkan penggabungan arah normal. Dan sebenarnya Anda bisa langsung menghitungnya dari bentuk matematika yang mendasarinya.
sumber
Saya melihat terutama tiga cara komputasi normals untuk bentuk yang dihasilkan.
Normal analitik
Dalam beberapa kasus Anda memiliki informasi yang cukup tentang permukaan untuk menghasilkan normals. Sebagai contoh, normal suatu titik pada bola adalah sepele untuk dihitung. Sederhananya, ketika Anda mengetahui turunan dari fungsi, Anda juga tahu yang normal.
Jika kasing Anda cukup sempit sehingga Anda dapat menggunakan normals analitik, maka kemungkinan besar akan memberikan hasil terbaik dalam hal presisi. Teknik ini tidak terlalu baik skala: jika Anda juga perlu menangani kasus di mana Anda tidak dapat menggunakan normal analitik, mungkin lebih mudah untuk menjaga teknik yang menangani kasus umum dan menjatuhkan analitik sama sekali.
Vertex normals
Produk silang dari dua vektor memberikan vektor tegak lurus terhadap bidang yang menjadi miliknya. Jadi mendapatkan normal segitiga adalah hal yang mudah:
Selain itu, dalam contoh di atas, panjang produk silang sebanding dengan area di dalam abc . Jadi normal yang dihaluskan pada titik yang dibagi oleh beberapa segitiga dapat dihitung dengan menjumlahkan produk silang dan menormalkan sebagai langkah terakhir, sehingga membebani setiap segitiga berdasarkan luasnya.
Jika Anda bekerja dengan paha depan, ada trik bagus yang dapat Anda gunakan: untuk quad abcd , gunakan
crossProduct(c - a, d - b)
dan itu akan menangani dengan baik kasus di mana quad sebenarnya adalah segitiga.Iñigo quilez menulis beberapa artikel pendek tentang topik: normalisasi cerdik , dan area poligon bersisi normal .
Normal dari turunan parsial
Normal dapat dihitung dalam shader fragmen dari turunan parsial. Matematika di baliknya sama, kecuali kali ini dilakukan di ruang layar. Artikel oleh Angelo Pesce ini menjelaskan teknik: Normal tanpa normal .
sumber