Bagaimana saya bisa menggunakan pipa grafik untuk membuat data volumetrik berdasarkan fungsi kepadatan?

12

Kedua grafik API (OpenGL dan DirectX) menyusun pipa yang terdefinisi dengan baik di mana beberapa tahap dapat diprogram. Tahap-tahap yang dapat diprogram ini harus mengambil jumlah data tetap minimum dan diharapkan melakukan berbagai operasi yang didefinisikan dengan baik di atasnya, dan mengeluarkan beberapa output minimum yang telah ditentukan, sehingga data dapat diteruskan ke tahap berikutnya dengan benar. Tampaknya seolah-olah pipa-pipa ini dirancang untuk bekerja dengan hanya sejumlah terbatas jenis data geometrik, yang dalam kasus D3D dan OGL adalah data titik dan koordinat tekstur.

Tetapi, jika diberikan kasus ketika aplikasi yang saya rencanakan untuk dibuat tidak menggunakan simpul (atau bahkan voxel) untuk merepresentasikan data geometrisnya dan tidak secara tepat melakukan transformasi atau proyeksi atau rasterisasi atau interpolasi atau semacamnya, keterbatasan API seperti itu. atau pipa membuat segalanya menjadi sulit.

Jadi, apakah ada cara di mana kita dapat mengubah grafik pipa dengan cara sehingga fungsionalitas apa yang dilakukan setiap tahap terhadap data dan jenis data yang dikeluarkan di setiap tahap diubah untuk keuntungan saya? Jika tidak, maka adakah cara agar saya dapat menggunakan fungsi API 'mentah' untuk membangun pipa saya sendiri? Jika tidak, tolong sebutkan mengapa itu tidak mungkin.

EDIT : Aplikasi Saya menggunakan fungsi kerapatan untuk merepresentasikan geometri. Fungsi memiliki nilai di setiap titik dalam ruang. Saya membagi frustrasi kamera menjadi kotak 3d, setiap blok dapat diproyeksikan sebagai piksel. Pada setiap blok, saya mengintegrasikan fungsi kerapatan dan memeriksa apakah nilainya lebih dari nilai yang diperlukan. Jika ya, maka diasumsikan bahwa ada sesuatu di blok itu dan piksel yang sesuai dengan blok itu diberikan. jadi, sekarang di renderer saya, saya ingin meneruskan fungsi (yang saya wakili dengan string) ke perangkat keras grafis alih-alih data vertex dalam buffer vertex. ini juga menyiratkan bahwa shader vertex tidak akan memiliki simpul untuk berubah menjadi ruang klip homogeni dan shader fragmen tidak mendapatkan info piksel. alih-alih, sekarang sebagian besar pencarian dan evaluasi terjadi per piksel.

Percikan Cahaya
sumber
Apakah 'fungsi kepadatan fungsi' adalah tautologi?
Pharap
@Pharap, itu salah ketik. itu hanya "fungsi desity" yang mewakili kehadiran "materi" di ruang.
The Light Spark
2
Sepertinya Anda hanya ingin membangun isosurface, yang merupakan masalah yang dipelajari dengan baik. Pernahkah Anda melihat http.developer.nvidia.com/GPUGems3/gpugems3_ch07.html atau mencari di Metaballs, visualisasi cloud titik, ekstraksi permukaan isosurface, atau rendering volume? Selain itu, kinerja seperti apa yang Anda butuhkan, yang akan membuat perbedaan besar pada pilihan teknik yang Anda cari ketika dikombinasikan dengan kompleksitas perhitungan Anda. Saya pikir Anda juga akan menemukan bahwa per-pixel akan menyebabkan berkilauan ketika kamera bergerak, dan sub-pixel akan diperlukan.
Patrick Hughes

Jawaban:

18

Anda benar-benar dapat menggunakan GPU untuk membuat data volumetrik.

Karena Anda ingin mengevaluasi serangkaian fungsi per piksel di layar, pendekatan sederhana adalah membuat segitiga layar penuh. Ini hanya sebuah segitiga tunggal yang menutupi seluruh layar (sebenarnya, ia mencakup lebih dari layar, karena layar tidak berbentuk segitiga, tetapi bagian-bagian di luar layar dibuang oleh GPU). Anda kemudian dapat menggunakan pixel shader (yang menerima koordinat layar dari pixel yang diarsirnya) untuk membuat sinar melalui volume Anda, mengevaluasi fungsi, apa pun yang perlu Anda lakukan.

(Berbeda dengan jawaban lain, saya tidak merekomendasikan penghitung komputasi karena kedengarannya seperti Anda ingin melakukan operasi per-piksel, dan segitiga layar penuh + piksel shader umumnya lebih efisien untuk itu daripada penghitung komputasi — walaupun menghitung shader juga akan bekerja.)

Metode segitiga layar penuh sangat umum dalam grafik waktu nyata untuk operasi pascaproses, sehingga Anda mungkin dapat menemukan semua informasi yang Anda butuhkan dengan sedikit googling.

BTW, mungkin menarik bagi Anda untuk membaca Rendering Worlds dengan Dua Segitiga oleh Iñigo Quílez, sebuah ceramah yang menjelaskan cara merender adegan 3D yang dikomposisikan menggunakan fungsi matematika (khususnya bidang jarak) menggunakan teknik shader piksel layar penuh.

Nathan Reed
sumber
Jadi apakah pixel shader menerima input sewenang-wenang (seperti string atau jenis objek yang ditentukan pengguna lainnya) sehingga saya dapat meneruskan fungsi saya?
The Light Spark
Saya ragu bahwa Anda ingin mencoba menjalankan parser dan / atau bahasa pada string fungsi arbitrer pada GPU, yang akan terasa canggung karena GPU tidak benar-benar tujuan umum. Kemungkinan besar Anda ingin membuat shader itu sendiri secara dinamis di kode utama Anda, lalu biarkan sistem grafis mengkompilasi dan menjalankan shader yang dihasilkan.
Patrick Hughes
@TheLightSpark Benar, Anda tidak akan meneruskan string ke shader (bahasa shading bahkan tidak memiliki tipe string), Anda ingin membuat dan mengkompilasi kode shader untuk fungsi yang Anda inginkan. Itu bisa dilakukan saat runtime jika perlu.
Nathan Reed
Mulai membaca jawaban Anda, saya membayangkan monitor berbentuk segitiga;) Apakah ada keuntungan menggunakan hanya satu segitiga daripada dua yang menutupi layar tanpa membuang piksel?
danijar
@danijar Ya, memiliki sedikit keunggulan dibandingkan menggunakan quad karena beberapa piksel diagonal akan diarsir dua kali jika Anda menggunakan quad layar penuh. Di sisi lain, membuang piksel di luar layar gratis karena rasterizer tidak akan menghasilkan piksel tersebut sejak awal.
Nathan Reed
6

Pelacakan ray dan teknik lainnya biasanya dilakukan dengan Compute Shaders, yang didukung Direct3D sejak rilis D3D11 dan OpenGL telah didukung sejak 4.3 (dan lebih lama melalui penggunaan OpenCL dan beberapa kontorsi).

Sean Middleditch
sumber
5

Kedengarannya sangat seperti Anda ingin menggunakan penghitung komputasi GPU, atau menggunakan objek "Penyangga Penyimpanan Shader" untuk membantu menambah pipa agar sesuai dengan kebutuhan Anda. Matematikawan, ilmuwan, dan orang lain yang melihat GPU untuk perhitungan pada hal-hal yang tidak benar-benar diterjemahkan ke dalam grafik standar menggunakan hal semacam ini.

Meskipun pipa grafis kontemporer sangat fleksibel, pengembang masih cenderung tersandung pada beberapa batasan. Namun, fitur komputasi shader membuat hidup lebih mudah bagi kita untuk tidak memikirkan tahap-tahap pipa karena kita terbiasa memikirkan vertex dan fragmen. Kami tidak lagi dibatasi oleh input dan output dari tahap pipa tertentu. Fitur Shader Storage Buffer Object (SSBO) misalnya telah diperkenalkan bersama dengan komputasi shader dan yang memberikan kemungkinan tambahan untuk bertukar data antara tahapan pipa, serta menjadi input dan output yang fleksibel untuk komputasi shader.

http://community.arm.com/groups/arm-mali-graphics/blog/2014/04/17/get-started-with-compute-shaders

Jika ini tidak mengarahkan Anda ke arah yang benar, maukah Anda memperluas konsep Anda yang tidak sesuai dengan paradigma vertex / fragmen?

AAorris
sumber
Saya mengedit jawaban saya untuk memasukkan apa yang saya lakukan. menghitung shader tampaknya menjadi jawaban, tetapi katakan saja jika ada hal lain yang dapat saya lakukan.
The Light Spark