Blogger Tips and TricksLatest Tips For BloggersBlogger Tricks

Terjemahan Buku Core Techniques and Algorithms in Game Programming - Shading

0

Posted by Octia Nuraeni | Posted in ,


Bab 17. Bayangan ( Shading )

"Saya melukis obyek seperti saya memikirkan mereka, tidak seperti saya melihat mereka."

- Pablo Picasso

Objek dunia nyata dan skenario ini tidak hanya ditentukan oleh geometri, bentuk, dan struktur. Kami juga sangat sensitif terhadap cahaya tampilan dan tekstur, dan bagaimana berinteraksi dengan bahan yang berbeda. Bayangkan pantai tanpa tekstur pasir atau lautan bergelombang yang tidak memantulkan sinar matahari dengan baik. Sebagian besar dari esensi suatu objek terletak di dalam sifat shading nya, dan itulah yang bab ini adalah semua tentang.

Dalam komputer grafis, shading adalah istilah yang sangat luas digunakan untuk mewakili semua proses yang terlibat dalam memberi warna pada pixel, yang pada gilirannya merupakan geometri. Bayangan (shading) biasanya dibagi menjadi dua besar daerah: sintesis bahan dan pencahayaan . Sintesis penawaran bahan dengan tekstur dan sifat permukaan, dan iluminasi menangani cahaya dan bayangan.

Bab ini berkaitan dengan komponen pencahayaan, sedangkan bab berikutnya dikhususkan untuk teknik berbasis tekstur. Berhati-hatilah, meskipun: Ini adalah pelajaran yang panjang, dan ratusan halaman bisa ditujukan untuk mereka. Mudah-mudahan, bab ini akan menunjukkan rutinitas inti, dan imajinasi Anda dan penelitian pribadi akan mengurus sisanya.

Iluminasi Dunia Nyata

Sebelum berbicara tentang algoritma pencahayaan untuk permainan real-time, mari kita berhenti dan melakukan gambaran tentang bagaimana pencahayaan nyata bekerja. Ini akan memberikan kita dengan dasar yang kuat dari mana algoritma perangkat lunak dapat diturunkan.

Cahaya adalah baik gelombang elektromagnetik dan aliran partikel (disebut foton), yang melakukan perjalanan melalui ruang dan berinteraksi dengan permukaan yang berbeda. Dalam ruang hampa, perjalanan cahaya tepat 299.792.458 meter per detik, atau sekitar 300 juta meter / detik. Kecepatan menurun sebagai media menjadi lebih resistif terhadap cahaya. Cahaya perjalanan lebih lambat di udara, bahkan lambat dalam air, dan sebagainya. Sebagai contoh, sebuah tim dari Harvard dan Stanford Universitas mampu memperlambat sinar cahaya untuk sesedikit 17 meter per detik (itu sekitar 40 mil per jam) dengan membuatnya menyeberangi gas atom natrium lewat dingin.

Berasal cahaya dari permukaan ketika atom mereka terpacu oleh panas, listrik, atau sejumlah reaksi kimia. Sebagai atom menerima energi, elektron mereka menggunakan energi yang masuk untuk berpindah dari orbit alami mereka untuk orbit yang lebih tinggi, banyak seperti lalu lintas di jalur cepat dari jalan raya. Cepat atau lambat, atom-atom ini akan jatuh kembali ke orbit normal, merilis sebuah paket energi dalam proses. Paket ini adalah apa yang biasa kita sebut satu foton. Sebuah foton memiliki tetap panjang gelombang dan frekuensi tergantung pada jenis perubahan orbital. Frekuensi menentukan warna cahaya dan juga jumlah energi sinar akan mengangkut. Di sisi energi yang lebih rendah, kita memiliki lampu merah dengan frekuensi 430GHz. Di ujung cahaya violet, yang memiliki frekuensi 730GHz. Beberapa warna, seperti
putih, tidak terkait dengan frekuensi tetap, tetapi dicapai dengan jumlah frekuensi yang berbeda dalam sinar di sebuah pola interferensi.

Tapi ingat bahwa cahaya menempati sebagian kecil dari spektrum frekuensi gelombang. Radio gelombang memiliki energi yang lebih rendah daripada cahaya tampak, sedangkan sinar-x dan sinar gamma mengangkut lebih banyak energi. Seperti perjalanan cahaya melalui ruang yang mungkin memukul obyek, dan bagian dari itu mungkin bangkit kembali. Ketika hit terjadi, foton
memukul elektron dari obyek, energi mereka, dan akhirnya mereka jatuh kembali, memancarkan foton baru. Jadi benar-benar apa yang Anda lihat adalah sinar cahaya sekunder yang sebenarnya dapat menjadi suatu frekuensi yang berbeda (dan dengan demikian warna) daripada yang pertama karena perubahan orbital dalam objek. Cara benda menyerap sebagian frekuensi dan dengan demikian menghasilkan cahaya dalam Pola warna tertentu membuat kita melihat warna pada objek. Dengan demikian, kita dapat melihat cahaya dari sumber cahaya atau dari suatu objek menyerap cahaya secara selektif. Tapi perhatikan bagaimana kedua kasus secara internal sama: Sebuah objek hanya cahaya sekunder source.

Ketika cahaya hits objek, sinar energi dibagi menjadi tiga komponen utama. Salah satu bagian yang diserap oleh objek, biasanya meningkatkan tingkat energi dalam bentuk panas. Anda merasa komponen bahwa setiap kali Anda berbaring di pantai yang cerah. Sebuah komponen kedua memantul dari permukaan dan menghasilkan sinar yang dipantulkan cahaya. Itulah yang kami melihat dalam cermin atau bahan reflektif. Sebuah berkas cahaya ketiga memasuki obyek (biasanya mengubah kecepatan karena variasi densitas antara kedua media) dan perjalanan melalui itu. Fenomena ini disebut refraksi atau transmisi , dan contoh terbaik adalah cahaya yang masuk laut. Perubahan kecepatan membuat cahaya sinar tikungan, kadang-kadang membuat kita berpikir benda direndam dalam media yang rusak (seperti jerami dalam segelas dilihat menyamping).

Dengan memahami penjelasan sebelumnya Anda dapat model fenomena yang paling ringan di dunia nyata. Shadows, untuk Misalnya, tidak lain adalah oklusi sinar cahaya oleh obyek buram, yang pada gilirannya membuat daerah (bayangan volume) terlihat lebih gelap. Glitter di puncak gelombang hanya pantulan sinar matahari dan hanya terjadi ketika orientasi gelombang memungkinkan untuk refleksi sempurna. Bahkan fenomena konsentrasi cahaya seperti hotspot disebabkan oleh lensa atau pola dalam kolam renang dapat dijelaskan. Sebagai sinar membiaskan memasuki air, mereka membungkuk. Karena banyak sinar membungkuk berkumpul di daerah kecil, itu berakhir menerima banyak energi, dan muncul dibakar. Sayangnya, sifat cahaya tidak dapat langsung diangkut ke komputer. Seperti kebanyakan atom- fenomena tingkat, jumlah data yang diperlukan untuk simulasi dunia nyata terlalu tinggi menurut standar sekarang.

Menghitung setiap adegan akan membutuhkan miliaran penembakan foton dan menjiplaknya sekitar TKP untuk model mereka perilaku akurat. Itulah yang beberapa algoritma render offline, seperti ray tracing atau radiositas, lakukan. Mereka adalah digunakan dalam penyaji komersial, tetapi mengambil apa pun dari menit ke hari untuk membuat satu frame.

Sebuah Rendering Persamaan Sederhana

Demi pemrograman game, sekarang kita akan membahas beberapa metode komputasi yang mensimulasikan cahaya interaksi. Kami akan mulai dengan algoritma relatif mudah digunakan dalam berbagai aplikasi grafis dan game.

Kemudian dalam bab ini, kita akan mengeksplorasi lebih terlibat solusi seperti Fungsi Distribusi reflektansi dua arah (BRDF). Namun untuk memulainya, kita akan menggunakan model yang menghitung pencahayaan dalam titik sebagai hasil dari tiga komponen:
  1. Ambient . Cahaya yang menyebarkan ke segala arah dan memberikan pencahayaan dasar ke TKP.
  2. Berdifusi . Cahaya yang dipantulkan dari permukaan ke segala arah. Jumlah cahaya yang dipantulkan sebanding dengan sudut insiden cahaya mencolok permukaan. Komponen ini adalah sudut pandang independen.
  3. Specular . Cahaya yang dipantulkan pada permukaan sepanjang arah cermin, yang menyumbang refleksi murni antara objek dan sumber cahaya. Seperti semua cermin, intensitas adalah melihat tergantung.

Berikut adalah persamaan pencahayaan global untuk model seperti itu:
Color = Ka*ambientColor + Kd*diffuseColor*(N dot L) + Ks*specularColor*(R dot V)shininess

Persamaan ini memiliki tiga komponen utama, satu untuk ambien, satu untuk menyebar, dan satu untuk specular. Mari kita tinjau setiap.

Ka, Kd , dan Ks melakukan kerusakan pada komponen pencahayaan. Bahan yang berbeda memiliki proporsi yang berbeda masing-masing, tetapi ketika ditambahkan, komponen ini harus 1. Nilai-nilai tipikal adalah Ka=0.2, Kd=0.5, and Ks=0.3, untuk contoh.

Tiga warna ( ambientColor , diffuseColor , dan specularColor ) adalah RGB triplet menentukan warna tiga komponen. Mereka dapat dihitung dengan menggunakan kriteria yang berbeda. The ambientColor , misalnya, biasanya putihatau beberapa warna halus yang ada hubungannya dengan siang hari warna: merah muda di malam hari, dan seterusnya. Alasan untuk menggunakan cahaya putih sebagai ambien adalah bahwa, secara umum, kita dapat mengasumsikan bahwa adegan memiliki banyak gelombang cahaya yang berbeda panjang gelombang, sehingga mereka menghasilkan cahaya putih bila dikombinasikan. Warna diffuse dan specular tergantung pada objek yang warna dan warna sumber cahaya.

Komponen specular, misalnya, biasanya diawali dengan warna sumber cahaya, sedangkan warna diffuse harus mengambil kedua permukaan dan warna cahaya menjadi pertimbangan. Secara intuitif, bola putih diterangi dengan cahaya biru tidak terlihat putih bersih, juga tidak terlihat biru murni. Jadi, dengan menggunakan teknik berikut umum:

ambientColor = putih
diffuseColor = surfaceColor * lightColor
specularColor = lightColor

Perhatikan bahwa ini adalah sebuah pendekatan. Alam tidak memiliki komponen ambient per se, dan mengalikan permukaan dan warna sumber cahaya untuk warna diffuse agak salah. Tapi hasilnya sangat baik dan dapat dihitung secara real waktu.
Sekarang, mari kita lihat sisa dari persamaan. Komponen difus adalah skala oleh ( N dot L ), di mana N adalah objek normal, dan L adalah vektor dari titik yang dinaungi ke sumber cahaya. Dengan asumsi kedua vektor adalah dinormalisasi, ini berarti kontribusi difus adalah jumlah total setiap kali cahaya jatuh pada obyek sejajar dengan yang normal dengan demikian, dengan cara yang sangat vertikal. Konfigurasi ini dipamerkan dalam Gambar 17.1 .

Gambar 17.1. Vektor normal dan ringan menjelaskan.
 

Semua cahaya kemudian bangkit kembali, dan kontribusi menyebar maksimal. Lalu, kontribusi specular adalah skala oleh ( R dot V ), di mana R adalah tercermin vektor cahaya, dan V adalah vektor melihat. Konfigurasi ini dipamerkan di Gambar 17.2

Gambar 17.2. Normal, cahaya, memantulkan cahaya, dan melihat vektor ilustrasi.

 

Secara intuitif, cahaya dipantulkan dari permukaan seperti cermin, dan jika kita angularly dekat dengan cermin yang (itulah yang R dot V artinya), kita melihat hotspot. Satu-satunya masalah adalah komputasi R dan V .

Berikut adalah persamaan:
V = vektor dari titik yang dinaungi dengan posisi kita
R = 2 * N * (N dot L) - L

Formulasi untuk R dapat memanfaatkan N dot L , yang sudah dihitung untuk komponen menyebar. Juga, perhatikan bagaimana kita menambahkan eksponen untuk persamaan. Secara intuitif, benda dipoles menunjukkan lebih kecil, lebih terfokus highlight, sehingga parameter shininess membantu kita model tersebut.
Berikut adalah persamaan umum yang menambahkan dukungan untuk berbagai sumber dan mengambil atenuasi mempertimbangkan:

Color = Ka*ambientColor + S(1/(kC+kL*di+kQdi2))*(Kd*diffuseColori* (N dot Li) + Ks*specularColori*(Ri dot V)shininess)

Perhatikan bahwa, kontribusi ambient independen sumber cahaya global ditambahkan ke jumlah individu kontribusi masing-masing lampu dalam adegan. Kemudian, masing-masing lampu memiliki komponen diffuse dan specular. Saya telah menambahkan i subindex untuk mewakili nilai-nilai yang harus dihitung per ringan, seperti warna dan vektor refleksi.

Sekarang, catatan pada faktor redaman: Dalam dunia nyata, cahaya diserap oleh jarak kuadrat. Hal ini sangat baik cocok untuk jarak yang besar hadir di dunia nyata, tetapi memberikan hasil yang aneh dalam komputer grafis. Jadi, baik OpenGL dan DirectX menggunakan model yang sedikit berbeda, dimana redaman adalah persamaan kuadrat umum berupa:
attenuation=1/(kC+kL*di+kQdi2)

Pada persamaan, di adalah jarak antara titik yang dinaungi dan sumber cahaya. Sekarang yang harus kita lakukan adalah tune kC, kL, and kQ parameter untuk mencapai hasil yang kita inginkan. Sebuah pelemahan konstan, misalnya, akan
dinyatakan sebagai (kC!=0, kL=kQ=0). Di ujung, persamaan kuadrat yang meniru dunia nyata akan dicapai dengan (kC=0, kL=0, kQ!=0). Dan atenuasi linier sangat populer digunakan oleh banyak permainan dicapai dengan kC=0, kL!=0, kQ=0.
Sebuah kata peringatan pada jenis-jenis persamaan: Ini adalah model ideal yang tidak mengambil banyak faktor pertimbangan. Bayangan, misalnya, perlu menggabungkan geometri adegan ke dalam persamaan. Apakah suatu titik dibayangan dari sumber cahaya, komponen diffuse dan specular yang baik akan dihilangkan sama sekali (untuk buram occluders) atau skala oleh nilai opacity (jika objek menyebabkan bayangan adalah semitransparan). Kita akan berbicara tentang
bayangan kemudian dalam bab dalam bagian mereka sendiri.

Per-Vertex dan Per-Pixel Pencahayaan

Cara pertama untuk menghasilkan efek pencahayaan meyakinkan pada permainan komputer adalah dengan menggunakan pencahayaan per-titik. Ini jenis pencahayaan dihitung pada simpul dari geometri saja dan disisipkan di antara. Dengan demikian, untuk menerangi segitiga kita akan menghitung persamaan pencahayaan di setiap salah satu dari tiga simpul. Kemudian, perangkat keras akan menggunakan tiga nilai untuk interpolasi penerangan dari seluruh segitiga.

Persamaan render dari bagian sebelumnya adalah pilihan yang populer karena dapat diimplementasikan dengan mudah. Bahkan, varian persamaan yang digunakan secara internal oleh kedua OpenGL dan DirectX penyaji. Tapi pencahayaan per-titik hanya dihitung sebagai simpul. Jadi apa yang akan terjadi pada dinding besar diwakili oleh hanya dua segitiga? Bayangkan bahwa kita menempatkan sumber cahaya tepat di tengah-tengah quad, jauh dari empat simpul. Di dunia nyata, sumber cahaya akan menciptakan hotspot sangat cerah di tengah dinding, tetapi karena kita tidak memiliki simpul di sana, pencahayaan per-titik akan terlihat benar-benar salah (lihat Gambar 17.3 ).

Gambar 17.3. Per-vertex (kiri) dibandingkan per-pixel (kanan) pencahayaan.


Kita perlu baik memperbaiki mesh (yang pasti akan berdampak pada bus dan GPU) atau menemukan cara yang lebih baik untuk naungan.

Di sinilah shading per-pixel tendangan masuk modus pencahayaan ini tidak menghitung pencahayaan hanya pada simpul, tetapi dalam setiap pixel di antara, sehingga pencahayaan memiliki resolusi yang lebih tinggi dan kualitas. Teknik seperti pemetaan cahaya (Dijelaskan dalam bagian berikutnya) atau shader fragmen (dijelaskan dalam Bab 21 , "Teknik Prosedural") digunakan untuk menghitung pencahayaan per pixel.

Tetapi jika pencahayaan per-vertex adalah apa yang Anda cari, ada dua pilihan. Anda dapat warna pencahayaan baik precompute dan menyimpannya sebagai warna per-vertex, atau Anda dapat meninggalkan tugas ini ke OpenGL atau DirectX mesin pencahayaan. Pertama pendekatan memiliki keuntungan menjadi lebih cepat karena tidak ada perhitungan yang dilakukan dalam loop real-time (pencahayaan adalah persamaan mahal). Di sisi lain, kontribusi specular tidak dapat precomputed karena pandangan tergantung. Pilihan kedua mengambil keuntungan dari saat ini generasi GPU, yang semua pencahayaan dukungan hardware dan mengubah.

Anda dapat menemukan contoh lengkap tentang bagaimana pencahayaan bekerja di Lampiran B , "OpenGL", dan Lampiran C , "Direct3D."


Referensi :

Anonim, Core Techniques and Algorithms in Game Programming,  http://www.tar.hu/gamealgorithms/ch17lev1sec1.html , 2 September 2009,  6:07:44 PM