Peta Bayangan Reflektif: Bagian 1

gambar

Halo, Habr! Saya mempersembahkan untuk Anda terjemahan artikel "Peta Bayangan Reflektif" oleh Eric Polman.

Reflective Shadow Maps (RSM) adalah algoritma yang memperluas peta bayangan "sederhana". Algoritma memperhitungkan cahaya yang tersebar setelah hit pertama di permukaan ( difus ). Ini berarti bahwa selain pencahayaan langsung, Anda mendapatkan pencahayaan tidak langsung. Pada artikel ini, saya akan menganalisis algoritme dari artikel resmi untuk menjelaskannya secara manusiawi. Saya juga akan secara singkat berbicara tentang pemetaan bayangan .

Pemetaan bayangan


Shadow Mapping (SM) adalah algoritma pembuatan bayangan. Menurut algoritme, kami menyimpan jarak dari sumber cahaya ke objek di peta kedalaman. Gambar 1 menunjukkan contoh peta kedalaman. Ini menyimpan jarak (kedalaman) untuk setiap piksel.

gambar
Gambar 1: Gambar ini menunjukkan peta kedalaman. Semakin dekat pikselnya, semakin terang itu.

Dengan demikian, ketika Anda memiliki peta kedalaman dalam hal sumber cahaya, Anda kemudian menggambar adegan dalam hal kamera. Untuk menentukan apakah suatu objek menyala, Anda memeriksa jarak dari sumber cahaya ke objek. Jika jarak ke objek lebih besar dari nilai yang disimpan di peta bayangan (kedalaman), objek berada di bayangan. Ini berarti bahwa subjek tidak boleh menyala. Gambar 2 menunjukkan contoh. Anda melakukan pemeriksaan ini untuk setiap piksel.

gambar
Gambar 2: Jarak dari sumber cahaya ke piksel dalam bayangan lebih besar dari jarak yang disimpan dalam peta bayangan.

Pemetaan bayangan reflektif


Sekarang setelah Anda memahami konsep dasar Pemetaan Bayangan , kami akan melanjutkan dengan Pemetaan Bayangan Reflektif (RSM). Algoritma ini memperluas fungsionalitas peta bayangan โ€œsederhanaโ€. Selain data kedalaman , Anda juga menyimpan posisi ruang-dunia (dalam sistem koordinat dunia), normalan ruang-dunia, dan fluks (keluaran cahaya). Saya akan menjelaskan mengapa Anda membutuhkan data ini.

Data


Posisi ruang-dunia


Dalam ruang dunia RSM , posisi harus disimpan untuk menentukan jarak antara piksel. Ini berguna untuk menghitung redaman cahaya. Cahaya memudar (menjadi kurang terkonsentrasi) ketika jarak tertentu berlalu. Jarak antara dua titik dalam ruang digunakan untuk menghitung intensitas cahaya.

Normal


Normals (ruang-dunia) digunakan untuk menghitung pantulan cahaya dari suatu permukaan. Dalam kasus RSM, mereka juga digunakan untuk menentukan apakah suatu piksel merupakan sumber cahaya untuk piksel lain. Jika kedua normalnya praktis bertepatan, mereka tidak akan saling memberi banyak cahaya yang dipantulkan.

Luminous Flux (Luminous Flux)


Fluks adalah intensitas cahaya dari sumber cahaya. Satuan ukurnya adalah lumen , istilah yang saat ini dapat Anda lihat pada paket bola lampu. Algoritma menyimpan fluks untuk setiap piksel saat peta bayangan digambar. Fluks dihitung dengan mengalikan intensitas cahaya dengan koefisien refleksi. Untuk cahaya directional, Anda mendapatkan gambar yang menyala seragam. Untuk cahaya spot, Anda juga mempertimbangkan sudut insiden. Atenuasi dan cosinus penerima (antara vektor normal dan cahaya) tidak diperhitungkan, karena ini diperhitungkan saat Anda mempertimbangkan pencahayaan tidak langsung. Artikel ini tidak akan membahas perinciannya. Gambar 3 menunjukkan tekstur spot light dari artikel resmi.

gambar
Gambar 3: Empat kartu yang terkandung dalam RSM digambarkan. Dari kiri ke kanan: peta kedalaman, posisi ruang-dunia, normal ruang-dunia, fluks.

Aplikasi data


Sekarang data dihasilkan (secara teoritis), saatnya untuk menerapkannya pada gambar akhir. Saat Anda menggambar gambar akhir, Anda menghitung efek dari setiap sumber cahaya pada setiap piksel. Selain hanya menyalakan piksel menggunakan sumber cahaya, Anda sekarang juga menggunakan Peta Bayangan Reflektif .

Pendekatan naif untuk menghitung kontribusi pencahayaan adalah melewati semua texels di RSM . Anda memeriksa untuk melihat apakah cahaya dari texel di RSM menyentuh piksel yang Anda hitung. Ini dilakukan dengan menggunakan posisi ruang-dunia dan ruang-dunia normal. Anda menghitung arah dari posisi ruang-dunia di texel RSM ke piksel. Kemudian Anda membandingkannya dengan normal menggunakan produk skalar vektor. Nilai positif apa pun berarti bahwa piksel tersebut harus diterangi menggunakan fluks , yang disimpan dalam RSM . Gambar 4 menunjukkan algoritma ini.

gambar
Gambar 4: Demonstrasi kontribusi pencahayaan tidak langsung berdasarkan posisi dan normalan ruang dunia.

Peta bayangan (dan RSM ) secara inheren besar (512x512 = 262144 piksel), jadi memeriksa setiap texel jauh dari optimal. Sebagai gantinya, yang terbaik adalah membuat sejumlah sampel dari peta. Jumlah sampel tergantung pada seberapa kuat perangkat keras Anda. Jumlah sampel yang tidak mencukupi dapat menghasilkan artefak seperti strip atau flicker.

The texels yang paling mempengaruhi hasil pencahayaan paling dekat dengan pixel yang dihitung. Metode pengambilan sampel, yang mengumpulkan sebagian besar sampel di dekat koordinat piksel, akan memberikan hasil yang lebih baik. Metode ini disebut "sampel penting" . Artikel resmi menjelaskan bahwa kepadatan sampel berkurang dengan kuadrat jarak dari piksel yang kita hitung.

Kita juga perlu mengukur intensitas sampel dengan mempertimbangkan faktor yang tergantung pada jarak. Ini disebabkan oleh fakta bahwa texel terletak lebih jauh, walaupun mereka lebih jarang disampel, pada kenyataannya, mereka mempengaruhi jumlah fluks yang sama. Oleh karena itu, dalam piksel yang jauh, Anda perlu meningkatkan intensitas untuk memuluskan ketidaksetaraan, sambil mempertahankan sejumlah kecil sampel. Gambar 5 menunjukkan cara kerjanya.

gambar
Gambar 5: Pentingnya pengambilan sampel. Lebih banyak sampel diambil dari pusat dan sampel diskalakan oleh faktor berdasarkan jarak mereka dari titik pusat. Diadaptasi dari artikel di RSM .

Opsional
Proyeksi piksel saat ini pada peta bayangan diambil sebagai titik (s, t). Dan koordinat sampling relatif terhadap (s, t) dihitung terlebih dahulu dan ditransfer ke shader sebagai array.

Anda harus memperlakukan sampel sebagai sumber penerangan titik. Anda menggunakan nilai fluks sebagai warna terang dan hanya sumber cahaya yang berseberangan dengan piksel.

Kesimpulan


Artikel resmi membahas lebih detail tentang optimasi lain dari algoritma ini, tapi saya akan membahasnya. Bagian Interpolasi Layar-Ruang menjelaskan bagaimana Anda dapat meningkatkan produktivitas, tetapi saya pikir sampling penting akan cukup untuk memulai.

Bagian kedua menyajikan implementasi RSM .

Source: https://habr.com/ru/post/id440488/


All Articles