Apakah ada cara untuk menghasilkan primitif dalam shader geometri tanpa geometri input?

17

Beberapa tahun yang lalu saya mencoba menerapkan Permata GPU ini di OpenGL untuk menghasilkan medan prosedural 3D menggunakan Marching Cubes . Artikel ini menyarankan untuk menerapkan Marching Cubes dalam geometri shader untuk efisiensi maksimum. Ini berarti saya perlu menjalankan shader sekali untuk setiap voxel di domain, dan itu akan menghasilkan seluruh geometri dalam sel itu.

Satu masalah yang saya temui adalah bagaimana menjalankan geometri shader tanpa benar-benar membuat apa pun di luar shader itu. Solusi saya (yang tampaknya agak berantakan) adalah membuat titik di setiap sel, membuangnya dengan geometri shader dan memancarkan segitiga saya sebagai gantinya. Saya tidak pernah menemukan solusi yang tepat dan solusi ini tetap dalam kode akhir.

Jadi, adakah yang memberi tahu OpenGL untuk memulai render pass dari geometri shader tanpa geometri input? Atau apakah saya harus selalu mengirim beberapa poin dummy ke GPU agar semuanya berjalan.

Martin Ender
sumber

Jawaban:

15

Tidak, sebenarnya tidak ada cara untuk melakukan itu.

Doa geometri shader memerlukan input primitif dan menghasilkan 0 atau lebih output primitif. Tanpa input primitif, sebenarnya tidak ada cara untuk benar-benar memanggil geometri shader . Tentu saja Anda dapat meregangkan batas jumlah maksimum primitif output geometri shader untuk setiap input primitif (tidak tahu batas praktis saat ini, mungkin berada di urutan ribuan mungkin). Jadi Anda mungkin dapat menghasilkan 1024 segitiga untuk setiap titik, tetapi Anda selalu harus memiliki beberapa input primitif.

Namun apa yang tidak Anda butuhkan adalah gagasan geometri yang sebenarnya. Anda tidak benar-benar harus membuat titik 3D di lokasi yang wajar, mereka juga bisa hanya memiliki beberapa indeks abstrak atau koordinat tekstur atau apa pun sebagai atribut dan tidak harus posisi 3D yang berarti. Noone menentukan atribut apa yang dimiliki simpul Anda. Dan Anda bahkan dapat membuat simpul tanpa atribut apa pun . Tetapi Anda harus membuat beberapa primitif untuk mengaktifkan shader geometri pada mereka, bahkan jika primitif tersebut tidak memiliki atribut aktual (bagaimana Anda kemudian menghitung geometri output Anda dalam shader geometri adalah pertanyaan yang berbeda, meskipun).

Tetapi apa yang sebenarnya Anda lakukan, memberikan titik untuk setiap sel kisi dan membuat segitiga kubus untuk sel itu, adalah pendekatan yang benar-benar lurus ke depan. Tentu saja atribut apa yang terkandung dalam sel ini terserah Anda, itu bisa berupa posisi 3D, texcoord menjadi tekstur 3D, apa pun, tetapi itu adalah sel-sel kotak yang Anda render. Murni diucapkan secara semantik, Anda tidak benar-benar "membuang" titik-titik itu dan kemudian "menggantinya" dengan segitiga, Anda "mengubah" setiap titik menjadi satu set segitiga. Persis seperti itulah gunanya geometri dan tidak ada yang "hacky" atau "tidak patut" tentang hal itu. Noone mengatakan bahwa geometri shader harus menghasilkan tipe primitif keluaran yang sama dengan input yang "tepat" .


Apa yang dapat Anda lakukan untuk mencapai cara input-kurang besar untuk merender grid voxel Anda (dan ini mungkin yang sebenarnya Anda minta) adalah dengan hanya menggambar satu set poin yang tidak berhubungan. Ini berarti Anda tidak memerlukan array atribut sama sekali dan cukup nonaktifkan semuanya dan aktifkan sederhana glDrawArraysdengan jumlah sel yang Anda butuhkan. Kemudian di vertex shader atau geometri shader Anda dapat menghasilkan indeks sel jaringan 3D yang diperlukan dengan sedikit indeks ajaib dari input vertex ID (yaitu gl_VertexID, yang merupakan satu-satunya informasi yang Anda miliki) dan kemudian menghitung geometri kubus marching Anda dari pencarian ke tekstur volume 3D (atau struktur data apa pun).

Jadi, dalam retrospeksi saya harus mengaitkan kembali pernyataan saya dari awal: Anda tidak dapat menghasilkan primitif tanpa input primitif , tetapi Anda dapat menghasilkan mereka tanpa input geometri .

Kata Chris Reinstate Monica
sumber