Bayangan dalam rendering yang ditangguhkan

12

Saya telah membaca beberapa materi tentang rendering yang ditangguhkan, dan saya pikir saya mendapatkan intinya. Tapi yang tidak saya mengerti adalah bagaimana hal itu menghasilkan bayangan. G-buffer, sejauh yang saya ketahui, tidak melibatkan pembuatan shadowmap untuk setiap cahaya, jadi saya bingung tentang bagaimana pass pencahayaan mengetahui apakah setiap pixel tersumbat atau tidak. Lagipula, pixel yang diberikan yang terlihat dari perspektif kamera mungkin sebenarnya tidak terlihat dari perspektif cahaya yang diberikan - dan bahwa geometri oklusi mungkin tidak terlihat dari perspektif kamera dan oleh karena itu tidak ada yang menuliskannya ke dalam buffer-G .

Jika Anda mulai merender shadowmaps, maka sepertinya hampir sama dengan forward rendering - Anda membuat semua geometri dalam adegan untuk setiap cahaya untuk membuat shadowmaps.

Jadi, bagaimana rendering yang ditangguhkan menghasilkan bayangan yang setara dengan rendering ke depan?

DeadMG
sumber

Jawaban:

14

Peneduhan yang ditangguhkan tidak melakukan sesuatu yang istimewa untuk bayangan. Anda masih perlu membuat peta bayangan secara normal dan kemudian membuat setiap cahaya dengan peta bayangan yang tepat terikat sebagai tekstur.

Ini masih lebih baik daripada merender maju karena Anda tidak perlu menggambar ulang pemandangan di tampilan utama untuk menerapkan pencahayaan. Menggambar peta bayangan seringkali jauh lebih murah daripada menggambar lebih banyak lintasan di tampilan utama karena Anda tidak perlu melakukan pixel shading, dan bayangan peta sering mengandung lebih sedikit adegan (Anda dapat menyisihkan lebih banyak barang).

Orang kadang-kadang melakukan "bayangan yang ditangguhkan" untuk satu cahaya, biasanya lampu directional utama. Alasan utama untuk melakukan ini adalah menggunakan peta bayangan bertingkat atau pendekatan lain yang menggunakan beberapa peta bayangan untuk cahaya yang sama. Anda dapat memesan satu saluran di buffer-G untuk masker bayangan (putih di mana menyala, gelap di mana teduh) dan menerapkan semua peta bayangan mengalir ke saluran buffer-G ini; maka shader untuk cahaya hanya membaca topeng bayangan dan mengalikannya menjadi warna terang. Ini bagus karena memisahkan bayangan dari bayangan, tetapi Anda masih menggambar semua peta bayangan yang sama.

Nathan Reed
sumber
1
Jika Anda sangat pintar, Anda bisa mencoba menggunakan geometri shader selama pembuatan GBuffer untuk 'inline' pembuatan peta bayangan (seperti sampel peta kubus DX10). Saya tidak yakin apakah itu sudah dilakukan, apakah itu mungkin atau apakah akan lebih lambat pada akhirnya - tetapi itu akan membawa pembuatan peta bayangan lebih dekat ke naungan yang ditangguhkan, atau ke dalam definisi tergantung pada agama Anda.
Jonathan Dickinson
6

Nah, apa itu peta bayangan? Peta bayangan adalah tekstur siapa yang menjawab pertanyaan sederhana: pada jarak berapa dari cahaya, sepanjang arah yang diwakili oleh texel, apakah cahayanya tersumbat? Koordinat tekstur dihasilkan menggunakan berbagai cara textive proyektif, tergantung pada algoritma pemetaan bayangan tertentu.

Tekstur projektif hanyalah cara mengubah objek menjadi ruang tekstur (dan ya, saya tahu itu terdengar mundur. Tapi begitulah cara kerjanya). Algoritma pemetaan bayangan menggunakan beberapa jenis transformasi. Tetapi pada akhirnya, ini hanyalah transformasi dari satu ruang ke ruang lainnya.

Saat merender peta bayangan, Anda mengambil simpul geometri Anda dan mengubahnya melalui pipa render standar. Tetapi kamera dan matriks proyeksi dirancang untuk posisi dan arah cahaya Anda, bukan untuk posisi tampilan dan orientasi.

Saat melakukan rendering maju dengan peta bayangan, Anda membuat objek seperti biasa, mengubah simpul menjadi ruang kamera tampilan dan melalui matriks proyeksi menonton. Namun, Anda juga mengubah simpul melalui kamera cahaya dan matriks proyeksi, meneruskannya sebagai data per-simpul ke shader fragmen. Ini menggunakan mereka melalui texturing proyektif untuk mengakses tekstur bayangan.

Inilah poin pentingnya. Akses tekstur proyektif dirancang sedemikian rupa sehingga lokasi yang diaksesnya pada tekstur mewakili arah antara titik di permukaan (titik yang Anda render dalam fragmen shader) dan cahaya. Oleh karena itu, ia mengambil texel yang mewakili kedalaman di mana oklusi terjadi untuk fragmen yang diberikan.

Tapi tidak ada yang istimewa dari pipa ini. Anda tidak perlu mengubah posisi simpul menjadi tekstur bayangan dan meneruskannya ke fragmen shader. Anda bisa meneruskan posisi verteks ruang-dunia ke shader fragmen, dan kemudian meminta shader fragmen mengubahnya menjadi ruang proyektif tekstur bayangan. Memang, Anda akan membuang banyak kinerja, karena Anda akan menghasilkan koordinat tekstur yang sama persis. Tapi ini layak secara matematis.

Memang, Anda bisa meneruskan tampilan posisi verteks ruang-kamera ke shader fragmen. Kemudian bisa mengubah mereka menjadi dunia, lalu menjadi ruang kamera cahaya, lalu menjadi ruang tekstur bayangan projektif. Anda dapat menempatkan semua transformasi itu menjadi satu matriks (tergantung pada algoritma proyeksi bayangan Anda). Sekali lagi, ini memberi Anda persis apa yang Anda miliki sebelumnya, jadi ketika meneruskan rendering, tidak ada alasan untuk melakukannya.

Namun dalam rendering yang ditangguhkan , Anda sudah memiliki posisi verteks ruang kamera. Anda harus, jika tidak, Anda tidak dapat melakukan pencahayaan. Anda menghabiskan banyak memori dan bandwidth dengan menuliskannya ke buffer, atau Anda pintar dan menghitungnya menggunakan buffer kedalaman dan berbagai matematika (yang tidak akan saya bahas di sini, tetapi dibahas secara online).

Apa pun yang terjadi, Anda dapat melihat posisi ruang kamera. Dan, seperti yang dinyatakan di atas, kita dapat menerapkan matriks untuk mengubahnya dari tampilan ruang kamera menjadi ruang tekstur projektif bayangan. Jadi ... lakukan itu. Kemudian akses peta bayangan Anda.

Masalah terpecahkan.

Nicol Bolas
sumber
Apakah mungkin untuk mengecualikan geometri per cahaya dalam rendering yang ditangguhkan (demi optimasi)?
Samaursa
@ Sasama: "Kecualikan geometri per cahaya" dari apa? Dari pergi ke peta bayangan? Dari yang menyala?
Nicol Bolas
Saya melihat Anda menjawab pertanyaan tentang itu, terima kasih. Bagi yang lain, jika mereka ingin mengikuti pertanyaan / jawaban: gamedev.stackexchange.com/q/178755/2287
Samaursa