Membuat normal vertex bersama di GPU

9

Saya sebagian besar berhasil porting implementasi Marching Cubes dari CPU ke OpenGL compute shaders, tapi saya belum menangani normals dan bertanya-tanya cara terbaik untuk melakukannya.

Implementasi saya berurusan secara khusus dengan bidang bernilai biner (saya mencoba memodelkan fungsi fraktal 3D yang belum memiliki penduga jarak), sehingga metode perbedaan gradien dan maju tidak akan berfungsi. Saya telah berbagi simpul yang berfungsi, dan implementasi CPU saya menggunakan metode Quilez yang dijelaskan di sini untuk mengakumulasi normals wajah ke setiap simpul tetangga.

Saya hanya bisa mem-port implementasi ini ke shader lain, tetapi masalah yang saya lihat dengan ini adalah banyaknya jumlah atom yang dibutuhkan. Karena kita hanya bisa menggunakan atom pada tipe integer skalar, dan saya tidak bisa memikirkan cara untuk mengemas 3 int yang ditandatangani menjadi 1 dengan cara yang dapat diringkas, itu berarti 3 sumbu * 3 simpul = 9 atom menambah per shader doa. Mereka akan tersebar di seluruh memori tentu saja sehingga tidak seperti memukul counter atom tunggal 9 kali, tetapi masih banyak sekali.

Alternatif lain adalah menjalankan shader invocation per-polygon dan membuat daftar wajah normal (saya mungkin bisa mengemas x10y10z10 dengan cara ini), lalu shader per-vertex untuk mengakumulasikan semua normals dari wajah tetangga. Ini akan menjadi babi memori yang sangat besar, ruang penyimpanan indeks wajah akan membutuhkan 12 int per titik untuk menangani kasus terburuk. Ada juga masalah bagaimana menulis ke dalam penyimpanan ini tanpa lagi menggunakan atom untuk mengetahui berapa banyak wajah yang telah ditulis ke titik tertentu.

Adakah yang punya ide lebih baik tentang bagaimana melakukan ini?

russ
sumber

Jawaban:

5

Untuk solusi nVidia saja Anda dapat menggunakan floating point atom add intrinsics (seperti NvInterlockedAddFp32) Membuka Kunci GPU Intrinsics di HLSL | Pengembang NVIDIA

Saya mencoba ini pada 80.000 vertex mesh dan cukup cepat (sekitar 1 atau 2 ms pada GTX980M, jika saya ingat dengan benar)

Berhati-hatilah dalam mengkompilasi shader Anda agar intrinsiknya berfungsi (karena bug / batasan nvidia)

Berhati-hatilah terhadap vertex splits (karena diskontinuitas UV misalnya), Anda harus menanganinya atau Anda akan memiliki tepi keras yang tidak diinginkan pada lapisan UV.

Florent Tournade
sumber
Karena pertanyaannya sudah lama saya akan meminta Anda sebagai gantinya :-) Untuk apa yang saya mengerti hanya memiliki informasi kedekatan untuk setiap titik tidak cukup baik untuk russ?
Andreas
Ini untuk proyek tesis saya tahun lalu, saya akhirnya hanya menggunakan cara bodoh dan menggunakan bilangan bulat atom, meningkatkan skala untuk memaksimalkan presisi, kemudian menormalkan vektor mengapung. Tidak dapat menemukan cara untuk membuat daftar wajah di sekeliling setiap simpul tanpa mengalokasikan ruang terburuk dan menggunakan penghitung atom untuk membuat daftar. Ini mungkin tidak efisien sekali, tetapi saya masih mendapat beberapa pesanan percepatan berkekuatan dari versi CPU dan tanda kelas satu jadi saya cukup senang dengan itu :)
russ