Naungan tangguhan - cara menggabungkan beberapa lampu?

9

Saya mulai dengan GLSL dan saya telah menerapkan shading yang ditangguhkan sederhana yang menghasilkan G-buffer dengan posisi, normal dan Albedo.

Saya juga menulis shader titik cahaya sederhana.

Sekarang saya menggambar bola untuk titik cahaya dan output masuk ke buffer pencahayaan.

Masalahnya adalah, bagaimana cara menggabungkan hasil buffer pencahayaan saat menggambar beberapa lampu?

Misalnya ketika saya menggambar lampu kedua ke lightbuffer menggunakan point light shader, bagaimana cara menambahkan lampu pertama ke lampu kedua di penyangga pencahayaan. Maksud saya, Anda tidak dapat membaca dan menulis ke buffer output yang sama?

JBeurer
sumber

Jawaban:

12

Campuran aditif, yaitu glBlendFunc (GL_ONE, GL_ONE) dan glEnable (GL_BLEND).

Nathan Reed
sumber
apakah pengujian mendalam harus dinonaktifkan untuk ini?
woojoo666
1
@ woojoo666 Tidak. Bahkan itu harus diaktifkan dengan tes kedalaman diatur ke kurang-sama, sehingga permukaan yang tepat sesuai dengan lintasan sebelumnya akan dilalui. Jika uji kedalaman tidak aktif, permukaan akan secara tidak benar mengumpulkan cahaya dari apa pun yang ada di belakangnya. :)
Nathan Reed
hmm, sepertinya memang itulah yang terjadi. menyalakan blending membuat wajah depan menyatu dengan wajah belakang, meskipun saya terus menguji kedalaman. apakah saya perlu melakukan sesuatu dengan topeng kedalaman juga?
woojoo666
melakukan sedikit lebih banyak pengujian, sepertinya masalah urutan gambar (menggambar depan-ke-belakang membuat pengujian kedalaman bekerja dengan benar dan hanya terjadi jika wajah saling melengkapi, back-to-front membuat semuanya menyatu). Apakah ada cara untuk melakukan ini tanpa memilah semuanya?
woojoo666
2
@ woojoo666 Aha, sepertinya Anda menyelesaikannya sendiri. Ya, Anda harus meletakkan kedalaman dalam celah buram sebelum Anda dapat menggunakan campuran apa pun. Ini bisa berupa z-prepass dengan penonaktifan warna dinonaktifkan, atau cara umum lainnya adalah dengan melakukan ambient / directional light di lintasan pertama tanpa blending, kemudian tambahkan lampu point / spot di lintasan kemudian dengan blending.
Nathan Reed
2

Untuk penyaji tangguhan saya, saya menggabungkan semua lampu menjadi satu target render cahaya menggunakan informasi dari buffer-g dan kemudian mencicipi target render untuk intensitas cahaya sambil membuat gambar backbuffer akhir saya.

Jadi pada dasarnya, saya menjalankan semua geometri permainan saya melalui kartu geometri untuk membangun g-buffer. Dari sana saya memberi makan buffer-g ke shader pass cahaya saya. Setiap lampu dijalankan melalui celah menggunakan quad layar penuh. Dengan cara ini pixel shader saya dapat menghitung intensitas cahaya untuk semua permukaan yang terlihat dari buffer-g dan kemudian menambahkannya ke target render cahaya. Anda cukup menambahkan intensitas cahaya untuk setiap cahaya ke buffer cahaya tetapi pastikan Anda menjepit intensitas dari 0 hingga 1.

Yang perlu Anda lakukan untuk menangani berbagai jenis lampu (titik, sorotan, paralel) adalah membuat cahaya melintas lebih kuat dengan menggunakan penyangga konstan untuk menentukan prosedur pencahayaan mana yang harus dijalankan.

KlashnikovKid
sumber
Ya, dan pertanyaannya adalah - bagaimana Anda menambah target render ringan? Menggunakan alpha blending seperti yang disarankan Nathan Reed? Karena sejauh yang saya tahu Anda tidak dapat membaca dan menulis ke buffer output yang sama (yang merupakan buffer cahaya dalam kasus ini).
JBeurer
Ups, ya. Saya membiarkan penggabungan output mengatasinya dengan campuran aditif. Ketika pengambilan sampel untuk gambar akhir adalah ketika Anda ingin menjepit nilai ke yang bekerja untuk saya sebagai intensitas cahaya maksimum yang mungkin diterima permukaan. Dari sana Anda bisa mengatur skala lampu Anda sesuai kebutuhan.
KlashnikovKid
Bagaimana Anda menangani kasing di mana ada lampu di belakang dinding dan tidak boleh menyalakan lampu di sisi lain dinding?
jjxtra
@ PsychoDad Itulah domain bayangan, yang merupakan ... topik yang lebih rumit. :)
Nathan Reed
0

Kemungkinan ada jawaban yang lebih baik dari ini, tetapi saya tahu, jika dalam shader Anda mengulangi kode yang diperlukan untuk melakukan cahaya kedua, Anda kemudian dapat memproses dua lampu pada satu objek, bukan satu. Itu memang membutuhkan droubling banyak kode untuk lampu kedua dan jahitannya sedikit berlebihan, tapi saya tahu itu berfungsi. Namun, saya percaya, karena seseorang mudah-mudahan akan menunjukkan untuk Anda, mungkin ada solusi yang lebih elegan.

CodeNeko
sumber
Tidak, itu tidak bekerja seperti itu. Saya menggambar bola untuk setiap titik cahaya. Kecuali cahaya titik kedua terletak dengan lingkup pengaruh cahaya pertama, cahaya kedua tidak akan ditarik. Metode Anda akan bekerja jika saya menggambar quad layar penuh untuk semua titik lampu, bagaimanapun, itu bukan pendekatan yang benar karena paha depan layar penuh digunakan untuk iluminasi global. Katakanlah saya memiliki 16 titik lampu kecil, yang akan memaksa saya untuk melewatinya untuk setiap piksel bahkan jika piksel tidak menyala olehnya. Dan biasanya saya akan mengatakan setiap piksel diterangi oleh satu atau dua lampu. Dan bagaimana jika saya memiliki 100 lampu? TIDAK
JBeurer
Alasan utama saya menyatakan ini, adalah jika Anda hanya menggunakan dua atau beberapa lampu, itu bisa membantu. Terutama jika Anda membuat banyak objek, menggunakan campuran berarti Anda perlu menggambar ulang adegan untuk setiap cahaya, jadi jika Anda memiliki banyak bentuk, katakan satu juta, atau sepuluh juta atau satu miliar, masing-masing undian membutuhkan biaya lebih banyak untuk dilakukan . Melakukannya di shader menyebabkan masalah jika Anda ingin banyak cahaya, tetapi memadukannya menyebabkan masalah jika Anda menginginkan banyak bentuk. Jika Anda memiliki banyak keduanya, Anda harus menemukan jalan tengah, tetapi biasanya Anda memiliki beberapa lampu dan banyak objek dalam permainan.
CodeNeko
Tidak, bayangan yang ditangguhkan tidak berfungsi seperti itu. Saya harus menggambar adegan hanya sekali dan menyimpan informasi yang relevan di G-Buffer. Kemudian bola pengaruh untuk setiap cahaya dan menyatu dengan penyangga cahaya. Dan akhirnya menggabungkan penyangga cahaya dengan colorbuffer saya mendapatkan buffer warna akhir yang diarsir. Jumlah perhitungan pencahayaan tidak tergantung pada kompleksitas pemandangan. Itulah keuntungan utama dari shading yang ditangguhkan di tempat pertama.
JBeurer
Ah, itu jauh lebih masuk akal dan akan jauh lebih baik.
CodeNeko