Cara kerja rendering game 3D: pencahayaan dan bayangan

Penerapan sebagian besar efek visual dalam game modern bergantung pada penggunaan pencahayaan dan bayangan secara bijaksana. Tanpa mereka, game akan membosankan dan tidak bernyawa. Pada bagian keempat dari analisis rendering game 3D, kami akan fokus pada apa yang terjadi di dunia 3D bersama dengan pemrosesan vertex dan pemetaan tekstur. Kami lagi akan membutuhkan banyak matematika, serta pemahaman yang kuat tentang dasar-dasar optik.

Bagian 1: pemrosesan simpul

Bagian 2: rasterisasi dan penelusuran sinar

Bagian 3: tekstur dan penyaringan tekstur

Ingat masa lalu


Sebelumnya, kami memeriksa aspek-aspek kunci dari memindahkan dan memproses objek dalam adegan, konversi mereka dari ruang tiga dimensi ke grid datar piksel, serta cara-cara untuk menerapkan tekstur pada objek-objek ini. Selama bertahun-tahun, operasi seperti itu telah menjadi bagian penting dari proses rendering, dan kita dapat melihatnya dengan kembali pada tahun 1993 dan meluncurkan Doom id Software.


Dengan standar modern, penggunaan cahaya dan bayangan dalam game ini sangat primitif: sumber cahaya tidak diperhitungkan, setiap permukaan berdasarkan simpulnya diberi nilai warna umum atau nilai cahaya sekitar . Semua tanda bayangan diciptakan berkat penggunaan tekstur yang licik dan pilihan warna lingkungan.

Tidak ada bayangan, karena mereka bukan tugas pemrogram: PC pada waktu itu adalah prosesor 66 MHz (yaitu, 0,066 GHz!), Hard drive 40 MB dan kartu grafis 512 kilobyte dengan kemampuan 3D minimal. Maju cepat 23: dalam reboot seri yang terkenal, kita melihat cerita yang sama sekali berbeda.


Banyak teknologi yang digunakan untuk membuat bingkai ini , ia menawarkan tahapan seperti oklusi ambient ruang layar, pemetaan kedalaman pra-pass, filter bokeh blur, operator koreksi nada, dan sebagainya. Perhitungan pencahayaan dan naungan setiap permukaan dilakukan secara dinamis: mereka terus berubah tergantung pada kondisi lingkungan dan tindakan pemain.

Karena setiap operasi rendering 3D memerlukan matematika (sejumlah perhitungan!), Lebih baik kita mulai dengan apa yang terjadi di balik layar dari setiap game modern.

Pencahayaan matematika


Untuk menerapkan semuanya dengan benar, kita perlu secara akurat mensimulasikan perilaku cahaya ketika berinteraksi dengan berbagai permukaan. Sangat mengherankan bahwa untuk pertama kalinya masalah ini mulai dipecahkan pada abad ke-18 oleh seorang pria bernama Johann Heinrich Lambert.

Pada 1760, seorang ilmuwan Swiss merilis sebuah buku berjudul Photometria . Di dalamnya, ia menjabarkan aturan-aturan dasar perilaku cahaya; yang paling luar biasa dari mereka adalah sebagai berikut - permukaan memancarkan cahaya (dengan refleksi atau sebagai sumber cahaya) sedemikian rupa sehingga kecerahan cahaya yang dipancarkan bervariasi tergantung pada kosinus sudut antara permukaan normal dan pengamat.


Aturan sederhana ini meletakkan dasar untuk apa yang disebut pencahayaan difus . Ini adalah model matematika yang digunakan untuk menghitung warna permukaan tergantung pada sifat fisiknya (misalnya, warna dan tingkat pantulan cahaya) dan lokasi sumber cahaya.

Dalam rendering 3D, ini membutuhkan banyak informasi, yang paling mudah untuk dibayangkan dalam bentuk skema seperti itu:


Kami melihat banyak panah pada gambar, ini adalah vektor , dan vektor berikut ini diperlukan untuk menghitung warna:

  • 3 vektor untuk posisi titik, sumber cahaya dan kamera melihat pemandangan
  • 2 vektor untuk arah sumber cahaya dan kamera dari sudut pandang titik
  • 1 vektor normal
  • 1 setengah vektor (selalu di tengah-tengah antara vektor arah pencahayaan dan kamera)

Mereka dihitung pada tahap pemrosesan simpul dari proses rendering, dan persamaan menyatukan mereka semua (disebut model Lambert) memiliki bentuk:


Yaitu, warna titik di bawah pencahayaan difus dihitung dengan mengalikan warna permukaan, warna sumber cahaya dan produk skalar dari vektor normal titik dan arah cahaya dengan koefisien redaman dan proyeksi pencahayaan. Operasi ini dilakukan untuk setiap sumber cahaya di tempat kejadian, karenanya simbol jumlah pada awal persamaan.

Vektor dalam persamaan ini (dan semua yang kita lihat di bawah) dinormalisasi (seperti yang ditunjukkan oleh ikon di atas setiap vektor). Vektor yang dinormalisasi mempertahankan arah aslinya, dan panjangnya berkurang ke nilai satuan (mis., Sama dengan 1 unit pengukuran).

Nilai warna permukaan dan sumber cahaya adalah angka RGBA standar (merah, hijau, biru, dan transparansi alfa). Mereka bisa bilangan bulat (misalnya, INT8 untuk setiap saluran warna), tetapi hampir selalu merupakan angka floating point (misalnya, FP32). Koefisien atenuasi menentukan bagaimana tingkat iluminasi berkurang ketika menjauh dari sumber, dan dihitung dengan persamaan lain:


Istilah A C , A L dan A Q adalah koefisien yang berbeda (konstan, linier, kuadratik) yang menggambarkan bagaimana jarak mempengaruhi tingkat pencahayaan. Semuanya diatur oleh programmer saat membuat mesin rendering. Di setiap API grafis, ini diterapkan dengan caranya sendiri, tetapi koefisien diperkenalkan ketika mengenkode jenis sumber cahaya.

Sebelum kita mempertimbangkan koefisien terakhir (lampu sorot), perlu dicatat bahwa dalam rendering 3D pada dasarnya ada tiga jenis sumber cahaya: titik, terarah dan sorotan.


Sumber titik memancarkan cahaya secara merata ke segala arah, dan sumber arah memancarkan cahaya hanya dalam satu arah (dari sudut pandang matematika, ini hanyalah sumber titik, jauh pada jarak tak terbatas). Lampu sorot adalah sumber arah yang kompleks karena memancarkan cahaya dalam bentuk kerucut. Cara cahaya bervariasi dalam tubuh kerucut menentukan ukuran bagian dalam dan luar kerucut.

Dan ya, untuk koefisien sorot, ada persamaan lain:


Nilai koefisien proyektor adalah 1 (mis., Sumbernya bukan proyektor), atau 0 (jika titik di luar arah kerucut), atau nilai yang dihitung antara keduanya. Sudut φ (phi) dan θ (theta) menentukan dimensi bagian dalam / luar kerucut lampu sorot.

Dua vektor: L dcs dan L dir (terbalik dengan arah kamera dan arah sorotan) digunakan untuk menentukan apakah kerucut dari titik tersebut bersentuhan.

Sekarang kita harus ingat bahwa semua ini diperlukan untuk menghitung nilai pencahayaan difus, dan semua operasi ini harus dilakukan untuk masing - masingsumber pencahayaan di tempat kejadian, atau setidaknya untuk setiap sumber yang ingin dipertimbangkan oleh programmer. Banyak persamaan ini dieksekusi oleh API grafis, tetapi mereka juga dapat dilakukan secara manual jika encoders membutuhkan kontrol lebih besar atas gambar.

Namun, di dunia nyata, pada kenyataannya, ada sumber cahaya dalam jumlah tak terbatas : setiap permukaan memantulkan pencahayaan, sehingga semuanya mempengaruhi pencahayaan keseluruhan dari pemandangan. Bahkan di malam hari ada pencahayaan latar belakang, apakah itu bintang dan planet atau cahaya yang tersebar di atmosfer.

Untuk mensimulasikan ini, nilai pencahayaan lain dihitung: pencahayaan sekitar .


Persamaan ini lebih sederhana daripada untuk pencahayaan difus karena arah tidak diperlukan. Di sini, perkalian sederhana dari berbagai koefisien dilakukan:

  • C SA - warna penerangan permukaan
  • C GA - sorot warna adegan 3D global
  • C LA - warna penerangan dari semua sumber cahaya di tempat kejadian

Perlu dicatat bahwa koefisien atenuasi dan proyektor digunakan lagi, serta penjumlahan dari semua sumber cahaya.

Jadi, kami memiliki pencahayaan latar belakang dan kami mempertimbangkan pencahayaan difus dari sumber cahaya dari berbagai permukaan dunia 3D. Tetapi model Lambert hanya berfungsi untuk material yang memantulkan cahaya dari permukaannya ke segala arah; benda yang terbuat dari kaca atau logam menciptakan jenis pantulan lain yang disebut specular ; Tentu, ada persamaan untuknya juga!


Bagian individual dari formula ini seharusnya sudah tidak asing lagi bagi Anda: kami memiliki dua nilai warna cermin (satu untuk permukaan - C S , yang lain untuk cahaya - C LS ), serta faktor redaman dan banjir yang biasa.

Karena refleksi specular sangat fokus dan terarah, dua vektor digunakan untuk menentukan kecerahan iluminasi specular: vertex normal dan semi-vektor. Koefisien p disebut kekuatan refleksi specular , ini adalah angka yang menentukan kecerahan refleksi tergantung pada sifat material permukaan. Dengan meningkatnya p, efek cermin menjadi lebih terang, tetapi lebih fokus dan lebih kecil.

Elemen terakhir yang harus dipertimbangkan adalah yang paling sederhana karena hanya berupa angka. Ini disebut pencahayaan memancarkan , dan diterapkan pada objek yang merupakan sumber langsung pencahayaan, yaitu, ke api, senter, atau Matahari.

Ini berarti bahwa sekarang kita memiliki satu set dan tiga set persamaan untuk menghitung warna titik permukaan, dengan mempertimbangkan pencahayaan latar belakang (lingkungan), serta interaksi antara sumber cahaya yang berbeda dan sifat-sifat bahan permukaan (difus dan specular). Pemrogram dapat memilih hanya satu atau menggabungkan keempat dengan hanya melipatnya.


Secara visual, kombinasi terlihat seperti ini:


Persamaan yang dipertimbangkan oleh kami diterapkan oleh grafik API (misalnya, Direct3D dan OpenGL) menggunakan fungsi standar mereka, tetapi untuk setiap jenis pencahayaan ada algoritma alternatif. Sebagai contoh, pencahayaan difus dapat diimplementasikan menggunakan model Oren-Nayyar , yang lebih cocok untuk permukaan yang sangat kasar daripada model Lambert.

Persamaan refleksi cermin dapat diganti dengan model yang memperhitungkan fakta bahwa permukaan yang sangat halus seperti kaca atau logam masih kasar, tetapi pada tingkat mikroskopis. Model semacam itu, yang disebut algoritma segi mikro , dengan mengorbankan kompleksitas matematika, memberikan gambar yang lebih realistis.

Model apa pun yang digunakan, mereka semua sangat ditingkatkan dengan meningkatkan frekuensi aplikasi mereka ke adegan 3D.

Perhitungan vertikal atau piksel-demi-piksel


Ketika kami memeriksa pemrosesan vertex dan rasterisasi , kami melihat bahwa hasil dari semua perhitungan pencahayaan rumit yang dilakukan untuk setiap vertex harus diinterpolasi di atas permukaan antar verteks. Ini karena sifat-sifat yang terkait dengan bahan permukaan disimpan di dalam simpul; ketika dunia 3D dikompresi menjadi kisi-kisi piksel 2D, piksel tersebut hanya tersisa di tempat simpul itu berada.


Sisa piksel perlu mengirimkan informasi tentang warna simpul sehingga warna tercampur dengan benar di permukaan. Pada tahun 1971, Henri Gouraud , seorang mahasiswa pascasarjana di Universitas Utah, mengusulkan metode yang sekarang disebut Gouraud Shading .

Metodenya cepat secara komputasi dan selama bertahun-tahun menjadi standar de facto , tetapi ia juga memiliki masalah. Dia tidak bisa menginterpolasi pencahayaan cermin dengan benar, dan jika objek itu terdiri dari sejumlah kecil primitif, maka pencampuran antara primitif tampak salah.

Solusi untuk masalah ini diusulkan pada tahun 1973 oleh Bui Tyong Fong, yang juga bekerja di Universitas Utah. Dalam artikel penelitiannya, Fong menunjukkan teknik untuk menginterpolasi normals dari simpul pada permukaan raster. Ini berarti bahwa model refleksi tersebar dan specular akan bekerja dengan benar untuk setiap piksel, dan kita dapat dengan jelas melihat ini dalam grafik komputer online David Eck dan tutorial WebGL.

Bola karbon yang ditunjukkan di bawah ini diwarnai dengan model pencahayaan yang sama, tetapi untuk perhitungan kidal dilakukan secara vertikal, diikuti oleh Gouraud shading untuk menyisipkannya di seluruh permukaan. Untuk bola di sebelah kanan, perhitungan dilakukan piksel demi piksel, dan perbedaannya jelas.


Gambar foto tidak menyampaikan semua peningkatan yang dibawa oleh bayangan Phong , tetapi Anda dapat secara independen menjalankan demo online Ek dan menonton animasinya.

Namun, Fong tidak berhenti di situ, dan beberapa tahun kemudian ia menerbitkan artikel penelitian lain di mana ia menunjukkan bagaimana perhitungan terpisah untuk ambient, diffuse, dan specular reflection dapat dilakukan dengan satu persamaan sederhana:


Di sini kita harus benar-benar mengerti! Nilai-nilai yang ditunjukkan oleh huruf k adalah konstanta refleksi untuk refleksi ambient, difus, dan specular. Masing-masing adalah sebagian kecil dari jenis yang sesuai dari cahaya yang dipantulkan dari besarnya cahaya yang datang; Nilai C yang kita lihat dalam persamaan di atas (nilai warna material permukaan untuk setiap jenis pencahayaan).

Vektor R adalah vektor "refleksi sempurna" - arah di mana cahaya yang dipantulkan akan bergerak jika permukaannya sangat halus; itu dihitung menggunakan permukaan normal dan vektor cahaya kejadian. Vektor C adalah vektor arah kamera; dan R dan C dinormalisasi.

Akhirnya, ada konstanta terakhir dalam persamaan: nilai α menentukan tingkat gloss permukaan. Semakin halus materialnya (mis. Semakin menyerupai kaca atau logam), semakin tinggi angkanya.

Persamaan ini biasanya disebut model refleksi Phong . Pada saat penelitiannya, proposal seperti itu radikal, karena memerlukan sumber daya komputasi yang serius. Versi model yang disederhanakan dibuat oleh Jim Blinn , menggantikan bagian rumus dari R dan C ke H dan N (vektor setengah-jarak dan permukaan normal). Nilai R harus dihitung untuk setiap sumber cahaya dan untuk setiap piksel dalam bingkai, danH cukup untuk menghitung satu kali untuk setiap sumber dan untuk seluruh adegan.

Model refleksi Blinn-Fong saat ini adalah sistem pencahayaan standar dan digunakan secara default di Direct3D, OpenGL, Vulkan, dll.

Ada banyak model matematika lainnya, terutama sekarang karena GPU dapat memproses piksel dalam shader yang panjang dan kompleks; bersama-sama, formula seperti itu disebut reflektansi dua arah / fungsi distribusi transmisi (BRDF / BTFD); mereka adalah dasar untuk mewarnai setiap piksel pada monitor ketika kita memainkan game 3D modern.

Namun, sejauh ini kami hanya menganggap permukaan yang memantulkan cahaya: bahan tembus cahaya mentransmisikan, sedangkan sinar cahaya dibiaskan. Dan beberapa permukaan. misalnya, air memantulkan dan mengirimkan cahaya ke berbagai tingkat.

Kami membawa pencahayaan ke tingkat yang baru


Mari kita lihat permainan Creed: Odyssey dari Assassin's 2018 , di mana pemain sering berlayar di atas air, baik di sungai dangkal dan di laut dalam.


Kayu dicat, logam, tali, kain, dan air - semua ini memantulkan dan membiaskan cahaya menggunakan banyak perhitungan.Untuk

rendering air yang paling realistis dengan tetap mempertahankan kecepatan permainan yang memadai, programmer Ubisoft menggunakan serangkaian trik. Permukaan air diterangi oleh trio akrab cahaya ambient, menyebar, dan specular, tetapi mereka dilengkapi dengan fitur menarik.

Yang pertama ini sering digunakan untuk menghasilkan sifat reflektif air - ini adalah refleksi ruang layar (SSR). Teknik ini menampilkan adegan, tetapi warna piksel bergantung pada kedalaman setiap piksel, mis. dari jarak ke kamera. Kedalaman disimpan dalam buffer yang disebut kedalaman. Kemudian bingkai diberikan lagi dengan semua pencahayaan dan tekstur yang biasa, tetapi adegan disimpan sebagai tekstur render , dan bukan sebagai buffer siap yang ditransmisikan ke monitor.

Setelah itu, barisan ray dilakukan . Untuk melakukan ini, sinar dipancarkan dari kamera dan jarak diatur sepanjang sinar. Kode memeriksa kedalaman balok relatif terhadap piksel dalam buffer kedalaman. Jika mereka memiliki nilai yang sama, kode memeriksa piksel normal untuk melihat apakah diarahkan ke kamera, dan jika demikian, mesin mencari piksel yang sesuai dari tekstur render. Kemudian satu set instruksi lebih lanjut membalikkan posisi piksel sehingga tercermin dengan benar dalam adegan.


Perintah SSR digunakan dalam mesin Frostbite EA.

Selain itu, cahaya tersebar selama pergerakan dalam bahan, dan untuk bahan seperti air atau kulit, trik lain yang disebut hamburan permukaan (SSS) digunakan. Kami tidak akan menjelaskannya secara rinci, tetapi Anda dapat membaca bagaimana ini digunakan untuk membuat hasil yang luar biasa dalam presentasi Nvidia 2014 .


Demo Nvidia 2013 FaceWorks ( tautan )

Mari kita kembali ke Assassin's Creed water: Implementasi SSS sulit terlihat di sini, dan karena pertimbangan kecepatan, itu tidak begitu aktif digunakan. Dalam game sebelumnya di seri AC, Ubisoft menggunakan SSS palsu , tetapi dalam game terakhir penggunaannya lebih rumit, tetapi masih tidak sebesar yang kita lihat di demo Nvidia.

Untuk mengubah nilai pencahayaan pada permukaan air, prosedur tambahan dilakukan yang mensimulasikan efek kedalaman dengan benar karena perubahan transparansi tergantung pada jarak ke pantai. Dan ketika kamera melihat air di dekat pantai, bahkan lebih banyak algoritma yang digunakan untuk memperhitungkan kaustik dan pembiasan.

Hasilnya mengesankan:


Assassin's Creed: Odyssey - memberikan air dengan segala kemuliaan.

Kami melihat air, tetapi bagaimana dengan pergerakan cahaya di udara? Partikel debu, uap air, dan elemen lainnya juga menyebabkan hamburan cahaya. Akibatnya, sinar cahaya menerima volume , dan tidak tetap hanya seperangkat sinar langsung.

Topik pencahayaan volumetrik dapat diperluas hingga selusin artikel, jadi kita akan berbicara tentang bagaimana permainan Rise of the Tomb Raider berurusan dengannya . Dalam video di bawah ini, hanya ada satu sumber utama pencahayaan - matahari bersinar melalui lubang di gedung.


Untuk membuat volume cahaya, mesin game mengambil piramida visibilitas kamera (lihat di bawah) dan secara eksponensial memecahnya menjadi 64 bagian. Kemudian, setiap irisan dirasterisasi ke dalam kisi-kisi dengan ukuran 160 x 94 elemen, dan semua data ini disimpan dalam tekstur render tiga dimensi dari format FP32. Karena tekstur biasanya dua dimensi, "piksel" volume piramida disebut voxel .


Untuk blok voxel 4 x 4 x 4, shader komputasi menentukan sumber cahaya aktif mana yang mempengaruhi volume ini, dan kemudian menulis informasi ini ke tekstur render tiga dimensi lainnya. Kemudian, untuk memperkirakan "kepadatan" cahaya total di dalam blok voxel, formula kompleks yang disebut fungsi hamburan Hengy-Greenstein digunakan .

Kemudian mesin melakukan beberapa shader lebih untuk memperbaiki data, setelah itu dilakukan marching ray sepanjang irisan piramida dengan akumulasi nilai kepadatan cahaya. Eidos-Montréal mengklaim bahwa di Xbox One semua operasi ini memakan waktu sekitar 0,8 milidetik!

Meskipun teknik ini tidak digunakan di semua gim, pemain berharap untuk melihat cakupan volumetrik di hampir semua gim 3D populer yang dirilis hari ini, terutama di gim tembak-menembak orang pertama dan gim aksi-petualangan.


Pencahayaan volumetrik yang digunakan dalam sekuel Rise of the Tomb Raider tahun 2018.

Awalnya, teknik pencahayaan ini disebut "sinar ilahi", atau, sebagaimana mereka disebut dalam istilah ilmiah, "sinar senja . " Salah satu game pertama yang digunakan adalah Crysis pertama Crytek, dirilis pada 2007.

Namun, ini bukan pencahayaan volumetrik yang benar - prosesnya termasuk rendering awal adegan dalam bentuk buffer kedalaman, yang digunakan sebagai topeng - buffer lain di mana warna piksel menjadi lebih gelap semakin dekat mereka ke kamera.

Penyangga topeng ini disampel beberapa kali, dan shader mengambil sampel dan mencampurnya dengan mengaburkan. Hasil operasi ini dicampur dengan adegan selesai:


Kemajuan kartu grafis selama 12 tahun terakhir telah luar biasa. GPU paling kuat pada saat rilis Crysis adalah Nvidia GeForce 8800 Ultra . GPU modern tercepat - GeForce RTX 2080 Ti memiliki daya komputasi lebih dari 30 kali, memori 14 kali lebih banyak, dan bandwidth 6 kali lebih banyak.

Dengan semua kekuatan komputasi ini, game modern dapat memberikan akurasi grafis yang lebih besar dan kecepatan keseluruhan, meskipun kompleksitas rendering semakin meningkat.


"Divine Rays" di Ubisoft's The Division 2

Tetapi pada kenyataannya, efek ini menunjukkan bahwa meskipun pentingnya pencahayaan yang benar untuk akurasi visual, ketiadaan cahaya sebenarnya bahkan lebih penting .

Esensi bayangan


Mari kita mulai bagian baru artikel dengan game Shadow of the Tomb Raider . Pada gambar di bawah, semua opsi grafik yang terkait dengan bayangan dinonaktifkan; di sebelah kanan mereka disertakan. Perbedaannya sangat besar, bukan?


Karena bayangan terbentuk secara alami di dunia nyata, permainan di mana mereka diterapkan secara keliru tidak akan pernah terlihat benar. Otak kita terbiasa menggunakan bayangan sebagai dukungan visual untuk menciptakan perasaan kedalaman, lokasi, dan pergerakan relatif. Tetapi melakukannya dalam game 3D sangat sulit, atau setidaknya sulit untuk melakukannya dengan benar.

Mari kita mulai dengan bebek. Di sini dia bergerak di sekitar lapangan, dan sinar matahari mencapai dia dan diblokir dengan benar.


Salah satu cara pertama untuk menerapkan bayangan dalam adegan adalah menambahkan "tempat" bayangan di bawah model. Ini sama sekali tidak realistis, karena bentuk bayangan tidak cocok dengan bentuk benda yang melemparkan bayangan; Namun, pendekatan ini cepat dan mudah dibuat.

Game 3D pertama, misalnya, Tomb Raider pertama tahun 1996, menggunakan metode ini karena perangkat keras pada waktu itu, misalnya, Sega Saturn dan Sony PlayStation, tidak dapat memberikan yang lebih baik. Metode ini melukis satu set primitif sederhana tepat di atas permukaan di mana model bergerak, dan kemudian menaungi mereka; menggambar di bagian bawah tekstur sederhana juga digunakan.


Metode lain yang pertama adalah memproyeksikan bayangan . Dalam hal ini, primitif yang memancarkan bayangan diproyeksikan ke sebuah pesawat yang berisi lantai. Bagian dari perhitungan matematika yang diperlukan untuk ini diciptakan oleh Jim Blinn di akhir 80-an. Dengan standar modern, ini adalah proses yang sederhana, dan ini berfungsi paling baik untuk objek statis sederhana.


Namun berkat optimalisasi, proyeksi bayangan memberikan penciptaan contoh-contoh bayangan dinamis pertama yang layak, misalnya, dalam game 1999 Kingpin: Life of Crime by Interplay. Seperti yang kita lihat pada gambar di bawah ini, hanya karakter animasi (bahkan tikus!) Memiliki bayangan, tetapi ini lebih baik daripada bintik-bintik sederhana.


Masalah yang paling serius dengan pendekatan ini adalah: (a) opacity bayangan sempurna, dan (b) metode proyeksi memancarkan bayangan pada satu permukaan datar (misalnya, di tanah).

Masalah-masalah ini dapat diselesaikan dengan menerapkan sebagian kecil transparansi ketika mewarnai proyeksi primitif dan melakukan beberapa proyeksi untuk setiap karakter, tetapi kemampuan perangkat keras PC pada akhir 90-an tidak dapat mengatasi render tambahan.

Teknologi modern untuk menciptakan bayangan


Cara yang lebih akurat untuk mengimplementasikan bayangan telah diusulkan jauh sebelumnya, sudah pada tahun 1977. Saat bekerja di University of Austin (Texas), Franklin Crowe menulis sebuah artikel penelitian di mana ia mengusulkan beberapa teknik menggunakan volume bayangan.

Secara umum, mereka dapat digambarkan sebagai berikut: proses menentukan primitif mana yang diarahkan ke sumber cahaya; tulang rusuk mereka diregangkan ke pesawat. Meskipun ini sangat mirip dengan memproyeksikan bayangan, perbedaan penting adalah bahwa volume bayangan yang dibuat kemudian digunakan untuk memeriksa apakah piksel berada di dalam / di luar volume. Berkat informasi ini, bayangan dapat dipancarkan di semua permukaan, bukan hanya tanah.

Teknik ini ditingkatkan pada tahun 1991 oleh Tim Heidmann, yang bekerja padaGrafis Silikon . Mark Kilgard terlibat dalam pengembangan lebih lanjut pada tahun 1999 , dan metode yang akan kami pertimbangkan dibuat pada tahun 2000 oleh John Carmack dari id Software (walaupun metode Carmack dibuka secara independen dua tahun sebelumnya oleh Bilodo dan Songa dari Creative Labs; ini menyebabkan bahwa Carmack terpaksa mengubah kodenya untuk menghindari masalah hukum).

Pendekatan ini membutuhkan rendering beberapa frame (disebut rendering multipass - proses yang sangat mahal di awal 90-an yang digunakan di mana-mana saat ini) dan konsep yang disebut buffer stensil .

Tidak seperti buffer dan kedalaman bingkai, itu tidak dibuat oleh adegan 3D itu sendiri - buffer ini adalah array nilai yang sama di semua dimensi (mis. Resolusi dalam x dan y ) dalam bentuk raster. Nilai yang tersimpan di dalamnya digunakan untuk memberi tahu mesin rendering apa yang harus dilakukan dengan setiap piksel dalam buffer bingkai.

Contoh paling sederhana untuk menggunakan buffer ini adalah menggunakan sebagai mask:


Metode dengan volume bayangan dilakukan seperti ini:

  • Kami membuat adegan ke frame buffer, tetapi hanya menggunakan pencahayaan sekitar (kami juga menyertakan semua nilai emisi di dalamnya jika pikselnya mengandung sumber cahaya)
  • , , ( (back-face culling)). (, ) . (.. «») - .
  • , (front-face culling) -, .
  • , , -.

Buffer stensil dan volume bayangan ini (biasanya disebut bayangan stensil) digunakan dalam permainan Doom 3 id Software 2004 :


Perhatikan bahwa permukaan karakter yang sedang berjalan masih terlihat melalui bayangan? Ini adalah keuntungan pertama dari proyeksi bayangan. Selain itu, pendekatan ini memungkinkan Anda untuk memperhitungkan jarak dari sumber cahaya (sebagai hasilnya, bayangan yang lebih lemah diperoleh) dan melemparkan bayangan pada permukaan apa pun (termasuk karakter itu sendiri).

Tetapi teknik ini memiliki kelemahan serius, yang paling terlihat adalah bahwa tepi bayangan sepenuhnya tergantung pada jumlah primitif yang digunakan untuk membuat objek yang melemparkan bayangan. Selain itu, multipassing dikaitkan dengan banyak operasi baca / tulis ke memori lokal, itulah sebabnya penggunaan bayangan stensil cukup mahal dalam hal kinerja.

Selain itu, ada batasan jumlah volume bayangan, yang dapat diperiksa menggunakan buffer stensil, karena semua API grafik mengalokasikan sejumlah bit yang cukup kecil di atasnya (biasanya hanya 8). Namun, karena biaya komputasi bayangan stensil, masalah ini biasanya tidak muncul.

Ada masalah lain - bayangan itu sendiri jauh dari realistis. Mengapa? Karena semua sumber cahaya - lampu, api terbuka, lentera, dan Matahari - bukanlah titik tunggal di ruang angkasa, mis. mereka memancarkan cahaya dari beberapa daerah. Bahkan dalam kasus paling sederhana yang ditunjukkan di bawah ini, bayangan nyata jarang memiliki tepi yang tajam.


Wilayah bayangan yang paling gelap disebut bayangan penuh (umbra); penumbra selalu merupakan bayangan yang lebih terang, dan batas antara keduanya sering kabur (karena biasanya ada banyak sumber cahaya). Sulit untuk memodelkan ini dengan buffer dan volume stensil, karena bayangan yang dibuat disimpan dalam bentuk yang salah sehingga dapat diproses. Pemetaan bayangan datang untuk menyelamatkan !

Prosedur dasar dikembangkan pada tahun 1978 oleh Lance Williams . Ini sangat sederhana:

  • Untuk setiap sumber cahaya, kami membuat adegan dari sudut pandang sumber ini, menciptakan tekstur kedalaman khusus (yaitu, tanpa warna, pencahayaan, tekstur, dll.). Resolusi buffer ini tidak harus sama dengan ukuran bingkai jadi, tetapi semakin tinggi semakin baik.
  • , ( x,y z) , .
  • : , .

Jelas, ini adalah prosedur multi-pass lain, tetapi langkah terakhir dapat dilakukan menggunakan pixel shader sehingga pemeriksaan kedalaman dan perhitungan pencahayaan selanjutnya digabungkan dalam satu pass. Dan karena seluruh proses pembuatan bayangan tidak tergantung pada jumlah primitif yang digunakan, itu jauh lebih cepat daripada menggunakan buffer stensil dan volume bayangan.

Sayangnya, teknik dasar yang dijelaskan di atas menghasilkan semua jenis artefak visual (misalnya, perspektif aliasing , "bayangan jerawat" , "peter panning"), yang sebagian besar terkait dengan resolusi dan ukuran bit dari tekstur kedalaman. Semua GPU dan API grafik memiliki keterbatasan yang mirip dengan tekstur, sehingga seluruh rangkaian teknik tambahan telah dibuat untuk menyelesaikan masalah ini.

Salah satu manfaat menggunakan tekstur untuk informasi mendalam adalah bahwa GPU dapat mengambil sampel dan memfilternya dengan sangat cepat dan dengan berbagai cara. Pada tahun 2005, Nvidia menunjukkan metode pengambilan sampel tekstur yang dapat menyelesaikan beberapa masalah visual yang disebabkan oleh bayangan standar. Selain itu, ia memberikan tingkat kehalusan tepi bayangan tertentu; teknik ini disebut penyaringan persentase lebih dekat .


Sekitar waktu yang sama, Futuremark mendemonstrasikan penggunaan cascaded shadow maps (CSM) di 3DMark06 . Ini adalah teknik di mana untuk setiap sumber cahaya beberapa tekstur kedalaman dibuat dengan resolusi yang berbeda. Tekstur resolusi tinggi digunakan di dekat sumber, dan lebih rendah - pada jarak dari sumber. Hasilnya adalah transisi bayangan yang lebih halus dalam adegan tanpa distorsi.

Teknik ini ditingkatkan oleh Donnelly dan Loritzen pada 2006 dalam prosedur varians shadow mapping (VSM) mereka, serta Intel pada 2010 dalam algoritma distribusi sampel (SDSM).


Menggunakan SDSM dalam Shadow of the Tomb Raider

Untuk meningkatkan kualitas gambar, pengembang game sering menggunakan gudang persenjataan lengkap, tetapi yang utama tetap pemetaan bayangan. Namun, ini dapat diterapkan hanya pada sejumlah kecil sumber cahaya aktif, karena jika Anda mencoba memodelkannya untuk setiap permukaan yang memantulkan atau memancarkan cahaya, laju bingkai akan secara serempak turun.

Untungnya, ada teknik nyaman yang bekerja dengan objek apa pun. Ini memberi kesan penurunan kecerahan pencahayaan mencapai objek (karena fakta bahwa ia atau benda lain menghalangi cahaya sedikit). Fitur ini disebut oklusi ambien.dan dia memiliki banyak versi. Beberapa dari mereka dirancang khusus oleh produsen perangkat keras, misalnya, AMD menciptakan HDAO ( oklusi ambien definisi tinggi ), dan Nvidia memiliki HBAO + ( oklusi ambient berbasis horizon ).

Versi apa pun yang digunakan, itu diterapkan setelah adegan sepenuhnya diberikan, oleh karena itu diklasifikasikan sebagai efek pasca-pemrosesan . Bahkan, untuk setiap piksel dihitung berapa banyak kita melihatnya di tempat kejadian (lebih lanjut tentang ini di sini dan di sini ) dengan membandingkan nilai kedalaman piksel dengan piksel yang mengelilinginya pada titik yang sesuai dalam buffer kedalaman (yang, sekali lagi, disimpan sebagai tekstur).

Mengambil sampel buffer kedalaman dan kemudian menghitung warna piksel akhir memainkan peran penting dalam memastikan kualitas oklusi ambien; seperti dalam kasus shadowing, semua versi oklusi ambien untuk operasi yang tepat mengharuskan programmer untuk dengan hati-hati mengkonfigurasi dan menyesuaikan kode tergantung pada situasinya.


Shadow of the Tomb Raider tanpa AO (kiri) dan dengan HBAO + (kanan)

Namun, ketika diterapkan dengan benar, efek visual ini meninggalkan kesan mendalam. Pada gambar di atas, perhatikan tangan, nanas, dan pisang orang tersebut, serta rumput dan tumbuh-tumbuhan di sekitarnya. Perubahan warna pixel HBAO + cukup kecil, tetapi semua objek sekarang terlihat lebih baik dibangun ke lingkungan (di sebelah kiri tampaknya seseorang tergantung di atas tanah).

Jika Anda memilih salah satu game terakhir yang dibahas dalam artikel ini, maka daftar teknik render yang digunakan saat memproses pencahayaan dan bayangan akan menjadi panjang dari artikel itu sendiri. Dan meskipun tidak semua gim 3D baru menawarkan semua teknologi ini, mesin gim universal seperti Unreal memungkinkan Anda mengaktifkannya secara opsional, dan toolkit (misalnya, perusahaan Nvidia) menyediakan kode yang siap dimasukkan ke dalam gim. Ini membuktikan bahwa mereka bukan metode ultramodern yang sangat terspesialisasi - yang dulunya milik pemrogram terbaik, sekarang mereka tersedia untuk siapa saja.

Kami tidak dapat menyelesaikan artikel ini tentang pencahayaan dan bayangan tanpa menyebutkan penelusuran sinar. Kita sudah membicarakan proses ini dalam seri artikel ini, tetapi tingkat perkembangan teknologi saat inimembutuhkan memasang dengan frame rate rendah dan pengeluaran uang tunai yang serius.

Namun, teknologi ini didukung oleh konsol generasi mendatang Microsoft dan Sony, yang berarti bahwa selama beberapa tahun ke depan, penggunaannya akan menjadi alat standar lain bagi para pengembang di seluruh dunia yang berupaya meningkatkan kualitas visual permainan. Lihat saja apa yang berhasil dicapai Remedy dalam game Kontrol terbarunya :


Kami telah menempuh perjalanan jauh dari bayangan palsu dalam tekstur dan pencahayaan ambient yang sederhana!

Bukan itu saja


Dalam artikel tersebut, kami mencoba untuk berbicara tentang perhitungan matematika dasar dan teknik yang digunakan dalam permainan 3D, yang membuatnya se serealistis mungkin. Kami juga memeriksa teknologi yang mendasari pemodelan interaksi cahaya dengan benda dan material. Tetapi semua ini hanyalah puncak gunung es.

Misalnya, kami melewatkan topik seperti pencahayaan hemat energi, lensa flare, bloom, render yang sangat dinamis, transfer cahaya, koreksi nada, kabut, aberasi kromatik, pemetaan foton, kaustik, radiositas - daftar ini berlanjut. Sebuah studi singkat akan membutuhkan 3-4 artikel lagi.

All Articles