Jenis algoritma naungan apa yang mungkin digunakan untuk membuat bayangan seperti ini?
yang saya buat adalah serupa tetapi semuanya dilakukan dengan API gambar 2D yang didukung oleh OpenGL sehingga tidak ada koordinat Z.
Selain itu, untuk tangan itu sendiri, saya benar-benar ingin mendapatkan nuansa teduh seperti terlihat di sini:
Saya hanya tidak yakin bagaimana mencapai tampilan yang teduh dekat dengan itu.
Jumlah kartu pasti akan berubah dan kartu-kartu itu terlempar ke atas meja jadi saya tidak bisa menggunakan jenis peta jenis apa pun.
Algoritma macam apa yang harus saya perhatikan (selain dari blur yang saya tahu harus saya lakukan?)
Terima kasih
Memperbarui
Saya membuat permainan kartu 2D. Saya ingin menambahkan dropshadows offset dari kartu, sedikit seperti:
Cara saya berpikir untuk melakukannya adalah:
- Pertahankan tekstur yang ukurannya sama dengan backbuffer.
Gambarlah persegi panjang gelap sebagai kartu darurat untuk tekstur itu.
Memburamkan tekstur itu.
- Tarik kartu saya ke tekstur itu.
- Lakukan pencahayaan tambahan pada kartu.
- Gambarlah tekstur ini ke backbuffer.
Pertanyaan saya adalah:
Apakah ini cara yang tepat untuk melakukan ini?
Apakah ada cara untuk melakukannya tanpa render ke tekstur (menjaga bitmap
sebesar backbuffer)?Apakah aman untuk mengasumsikan bahwa ukuran tekstur maksimum tidak akan
dilampaui oleh ukuran backbuffer? (Maksud saya adalah, jika backbuffer
adalah 2000x3000, apakah aman untuk mengatakan bahwa saya dapat membuat tekstur dalam
memori video sebesar itu?
Terima kasih
sumber
Jawaban:
Saya pikir semua orang memberikan solusi terlalu rumit untuk masalah ini ..
Jadi pertama-tama, kita memiliki kartu (atau apa pun yang ingin Anda gambar), digambarkan di sini oleh (a). Selanjutnya, kami mengambil salinannya, mengisinya hitam dan menjalankan gaussian blur di atasnya (b). Semua ini terjadi di photoshop atau apa pun alat seni favorit Anda.
Selanjutnya, dalam gim, ketika kita ingin menggambar kartu, pertama menggambar gambar hitam kabur dengan campuran multiplicative (atau alfa), mengimbangi sedikit arah, dan kemudian menggambar kartu di atas itu. Voila.
Untuk tipuan lebih lanjut, Anda dapat berganti-ganti antara bayangan dan pembuatan kartu untuk mendapatkan efek seperti (d), atau pertama menggambar semua bayangan dan kemudian kartu, seperti dalam (e) (Saya mewarnai kartu dalam kasus (e) untuk menunjukkan bahwa mereka masih terpisah =)
Sebaiknya jangan menggunakan hitam murni (atau alfa penuh) untuk bayangan untuk membuat bayangan transparan yang lebih halus.
sumber
Yang pertama tidak terlalu sulit. Jika Anda merender saluran alfa untuk kartu Anda (yang bisa sesederhana hitam untuk piksel dengan kartu di dalamnya, dan putih untuk transparan), Anda dapat melakukan segala jenis blur yang Anda inginkan pada saluran alpha saja, dan kemudian diimbangi dan gunakan itu untuk mengontrol pencahayaan meja. (Agaknya, jika Anda tidak memiliki buffer-Z, Anda harus terlebih dahulu membuat saluran alpha offscreen di suatu tempat, kemudian melakukan tabel dengan mask, kemudian membuat kartu yang sebenarnya.)
Yang kedua mirip SSAO (oklusi ambien layar-ruang). Teknik itu membutuhkan koordinat Z. Namun, jika Anda tidak memiliki sudut yang berbeda antara kartu (yang saya kira jika Anda tidak memiliki Z-buffer), Anda mungkin dapat melakukan perkiraan yang cukup baik dengan membuat drop shadow (seperti yang pertama) untuk setiap kartu. kartu. Namun, kinerjanya bisa sedikit rumit — setiap pesawat akan membutuhkan saluran alfa kabur untuk semua pesawat di atasnya, dan jika ada banyak kartu di atas meja, itu bisa berarti beberapa render lintasan.
sumber
Bisakah Anda tidak membuat peta bayangan? Ubah adegan menjadi fbo. Simpan hanya nilai kedalaman dan lakukan pemeriksaan nilai kedalaman normal di shader untuk melihat apakah bayangan harus ditampilkan atau tidak.
sumber
Proses berikut ini tidak memerlukan target render di luar layar. Namun, dengan melakukan hal itu, ia mendapatkan persyaratan bahwa tabel harus diambil terlebih dahulu . Atau setidaknya, tidak ada yang ditarik pada piksel yang akan dicakup tabel sebelum tabel ditarik. Ini juga mensyaratkan bahwa tabel itu sendiri menjadi satu, tunggal, bagian yang tidak tumpang tindih: sebuah gambar.
Selain itu, framebuffer Anda membutuhkan komponen alfa.
Dapatkan gambar skala abu-abu dari sebuah kartu. Buat menjadi kabur di sekitar tepinya, mungkin memperluas ukurannya. Ini adalah gambar kartu bayangan Anda. Perhatikan bahwa ini adalah gambar saluran tunggal. Saat Anda mengakses tekstur ini di shader Anda, Anda harus memastikan bahwa Anda memasukkan nilai tunggal dalam komponen alpha. Ini bisa dilakukan di shader Anda atau di tempat lain.
Nilai 0,0 pada gambar berarti tidak ada bayangan. Nilai 1,0 pada gambar berarti bayangan total . Itu benar-benar gelap gulita. Anda mungkin menginginkan nilai 0,5 atau lebih sebagai warna tergelap Anda.
Bersihkan layar sedemikian rupa sehingga alpha diatur ke nol .
Sebelum merender apa pun (atau setidaknya apa pun yang akan ditampilkan "di bawah" tabel), untuk setiap kartu, render tekstur fuzzy, diimbangi dari posisi aktual kartu (tetapi dengan orientasi yang sama). Output warna oleh shader harus Konfigurasi konfigurasi untuk ini seharusnya (dalam bahasa OpenGL):
Mode campuran ini digunakan untuk menjaga bayangan yang tumpang tindih agar tidak bertambah gelap atau terang. Ini hanya mengambil nilai paling gelap yang ditulis ke piksel itu. Seharusnya terlihat cukup baik.
Anda juga harus menggunakan masker tulis warna untuk mematikan penulisan warna.
Berikan meja. Saat melakukannya, Blending harus diatur sebagai berikut:
Jika batasan terlalu ketat untuk Anda, maka Anda harus menggunakan target render. Ini dilakukan sebagai berikut:
Buat gambar kartu bayangan seperti sebelumnya.
Pertama, berikan bayangannya. Bind the shadow framebuffer (yang hanya perlu menjadi gambar saluran tunggal, jika perangkat keras Anda dapat merender ke salah satunya). Hapus nilainya menjadi nol.
Untuk setiap kartu, render gambar kartu bayangan, offset seperti sebelumnya. Shader Anda harus menuliskan nilai yang sama untuk keempat komponen warna keluaran. Modus campuran lagi harus
glBlendEquation(GL_MAX)
.Beralih kembali ke framebuffer biasa. Gambarlah semua yang Anda inginkan untuk dibayangi.
Sekarang gambar quad layar penuh dengan gambar bayangan yang kami render. Shader harus menyimpan texel yang diambil dari bayangan gambar di alfa output; RGB tidak relevan. Mode campuran harus:
sumber
Saya akan menggunakan buffer stensil. Kosongkan ke 1 (sebaiknya pada saat yang sama saat Anda membersihkan kedalaman), gambarkan meja Anda. Kemudian aktifkan uji stensil, gambar bayang-bayang menggunakan tekstur persegi panjang buram, bertambah jika stensil dan kedalaman melewati, tidak melakukan apa-apa jika stensil gagal, tidak ada jika kedalaman gagal, dan atur fungsi stensil Anda menjadi GL_EQUAL (ref 1, mask 0xff), nonaktifkan uji stensil . (Saya belum sepenuhnya menguji ini tetapi ini berasal dari kode yang tidak sama dan harus berfungsi dengan baik; Anda mungkin perlu mengubah params). Kemudian gambar semuanya.
Panggilannya adalah:
Satu-satunya waktu yang dapat menyebabkan masalah adalah jika Anda memiliki dua tepi buram yang sedikit tumpang tindih; jika tidak, tidak perlu apa-apa lebih dari apa yang ditawarkan OpenGL 1.1 dasar dan akan bekerja pada semua perangkat keras (mungkin kartu 3DFX yang sudah ada, yang saya anggap Anda tidak terlalu khawatir tentang dukungan ...)
Alternatif kedua, yang seharusnya bekerja dengan sangat baik di gim non-kinerja-kritis, adalah glCopyTexSubImage2D. Itu akan bekerja dengan tekstur yang lebih kecil daripada backbuffer juga dan juga didukung dengan baik pada semua perangkat keras (itu bagian dari OpenGL 1.1 dan Doom 3 yang menggunakannya, sehingga Anda dapat mengharapkan dukungan menjadi sangat baik).
Pengaturan dasar akan seperti ini:
Itu juga harus bekerja dengan sangat baik, ini sedikit lebih intensif daripada metode buffer stensil tetapi menangani kasus yang tumpang tindih dengan benar dan - seperti yang saya katakan - saya pikir permainan seperti game Anda akan memiliki kekuatan GPU untuk dibakar, bahkan pada low-end kartu.
sumber