Secara terprogram menghasilkan vertex normals

11

Saya bekerja dengan api wajah Kinect, ini menyediakan array dari simpul dan indeks untuk segitiga yang akan dibuat untuk membuat gambar wajah.

Tidak ada simpul dan urutannya dalam array serta indeks yang diberikan oleh kinect selalu konstan.

Namun api tidak memberikan informasi tentang data UV dan normals vertex.

Aplikasi ini mengharuskan saya untuk menjaga urutan simpul yang diberikan oleh kinect karena posisi mereka di ruang 3d berubah sesuai gerakan wajah sehingga menghasilkan uv dan normals dalam perangkat lunak pengeditan 3d tidak diragukan.

Saya berhasil menghasilkan UV dengan memproyeksikan posisi simpul ke bidang 2D karena ada sangat sedikit simpul pada bidang yang sama.

Namun, saya tidak tahu bagaimana menghasilkan vertex normals untuk mesh, tanpa vertex normal mesh wajah menarik tanpa kedalaman fitur-fiturnya dari prespektif, meskipun siluet terlihat karena posisi vertex sudah benar.

Saya mengerti bahwa karena tidak adanya vertex normals pencahayaan tidak akan bekerja dengan benar di atasnya dan karenanya mesh tanpa sifat pucat itu terlihat sekarang.

jadi bagaimana cara menghasilkan vertex normals ketika semua yang saya miliki hanyalah posisi vertex dan indeks verteks untuk membuat segitiga dari itu?

Allahjane
sumber
n = (v1 - v0) x (v2 - v0), di mana v0, v1, dan v2 adalah simpul dari wajah (segitiga) yang dimaksud. Pesanannya importan. Normalisasikan jika Anda benar-benar perlu. (dan xmerupakan produk silang)
3Dave

Jawaban:

14

Komputasi normal dari posisi vertex cukup sederhana menggunakan produk lintas vektor.

Produk silang dari dua vektor dan v (catat u × v , atau kadang-kadang u v ) adalah vektor yang tegak lurus terhadap u dan v , dengan panjang | | u × v | | = | | kamu | | | | v | | s i n ( θ ) , dengan θ sudut antara u dan vkamuvkamu×vkamuvkamuv||kamu×v||=||kamu||||v||ssayan(θ)θkamuv. Arah vektor akan tergantung pada urutan perkalian: adalah kebalikan dari v × u (dua arah yang tegak lurus terhadap bidang).kamu×vv×kamu

Jika Anda tidak terbiasa dengan produk silang, saya mengundang Anda untuk membacanya dan merasa nyaman dengannya. Normalnya akan tampak sederhana.

Normal shading datar

Jika Anda memiliki segitiga , A B × A C adalah vektor tegak lurus terhadap segitiga dan dengan panjang yang proporsional dengan luasnya. Karena yang normal adalah vektor satuan yang tegak lurus terhadap bidang segitiga, Anda bisa mendapatkan yang normal dengan:SEBUAHBCSEBUAHB×SEBUAHC

N=SEBUAHB×SEBUAHC||SEBUAHB×SEBUAHC||

Dalam kode, ini akan terlihat seperti n = normalize(cross(b-a, c-a))misalnya. Cukup terapkan ini di semua wajah Anda dan Anda akan memiliki normals Anda per wajah.

For each triangle ABC
    n := normalize(cross(B-A, C-A))
    A.n := n
    B.n := n
    C.n := n

Perhatikan bahwa ini mengasumsikan simpul tidak dibagi di antara segitiga. Saya tidak terbiasa dengan API Kinect; sangat mungkin bahwa mereka dibagikan, dalam hal ini Anda harus menduplikasi mereka, atau beralih ke solusi berikutnya:

Normal shading normal

Setelah pencahayaan dengan normal dihitung seperti di atas, Anda akan melihat bahwa tepi segitiga terlihat jelas. Jika ini tidak diinginkan, Anda dapat menghitung normal normalnya, dengan memperhitungkan semua wajah yang berbagi titik yang sama.

T1T2T3NN1N2N3T1T2NN1N2

Ingat bagaimana produk silang proporsional dengan area? Jika Anda menjumlahkan produk silang kemudian menormalkan jumlah, itu akan melakukan persis jumlah tertimbang yang kita inginkan. Jadi algoritme menjadi:

For each vertex
    vertex.n := (0, 0, 0)

For each triangle ABC
    // compute the cross product and add it to each vertex
    p := cross(B-A, C-A)
    A.n += p
    B.n += p
    C.n += p

For each vertex
    vertex.n := normalize(vertex.n)

Teknik ini dijelaskan lebih rinci pada artikel ini oleh Iñigo Quilez: normalisasi cerdas dari sebuah mesh .


Untuk lebih lanjut tentang normals, lihat juga:

Julien Guertault
sumber
Saya akan segera mencobanya dan kembali dengan hasilnya
Allahjane
Ini bekerja Terima kasih seorang pria, itu bekerja persis seperti yang saya inginkan
Allahjane
@Allahjane: senang mendengarnya bekerja dengan baik. :)
Julien Guertault