Bisakah saya mencapai efek obor (area yang lebih terang di sekitar sumber cahaya) dalam game 2D?


16

Saya berpikir untuk menulis sendiri game 2D sederhana. Itu tidak akan bersinar dengan grafis atau gameplay yang sempurna pada awalnya, tapi saya akan menganggapnya sebagai langkah pertama saya dalam pengembangan game PC. Jadi, bayangkan game 2D sederhana berbasis sprite (seperti Heroes IV atau Startcraft BroodWar).

Saya ingin gameplay mendukung hari / malam dengan perubahan pencahayaan yang sesuai dan pada saat yang sama akan gila harus membuat sprite untuk setiap nuansa pencahayaan. Jadi, saya memutuskan menambahkan lapisan semi-transparan di atas objek lain sudah cukup.

Masalah dengan solusi ini adalah jika saya memiliki objek sumber cahaya dalam permainan (seperti pahlawan mengenakan obor, atau gedung yang terbakar), pasti ada area yang lebih terang di sekitarnya, kan? Karena saya meletakkan lapisan semi-transparan saya di atas segalanya, bagaimana Anda menyarankan untuk mencapai efek visual torchligt yang saya inginkan? Mungkin menggambar ulang layer itu dengan menambahkan 'celah' atau area berwarna berbeda berdasarkan efek pencahayaan?


2
Topeng mungkin cara untuk pergi
Gustavo Maciel

5
"Torchlight" dalam judul bisa membingungkan karena game bernama Torchlight.
Tetrad

4
@Tetrad Harus ok selama tidak dikapitalisasi. Bagi saya, Torchlight tidak muncul sama sekali sampai membaca komentar Anda.
famousgarkin

Meskipun demikian, saya menyarankan edit untuk membuat judul lebih spesifik.
famousgarkin

Jawaban:


12

Saya tidak tahu apa yang Anda pemrograman, tapi ini adalah bagaimana saya menanganinya di XNA:

  1. Pada panggilan undian, sebuah List<Light>objek dibuat / dihapus.
  2. Selama loop menggambar ubin, setiap ubin diperiksa untuk melihat apakah ada Lampu yang terkait dengannya. Jika ya, Lightobjek akan ditambahkan ke List<Light>.
  3. Ubinnya digambar sendiri RenderTarget2D.
  4. Setelah loop ubin, daftar Lights iterasi dan digambar sendiri RenderTarget2Dmenggunakan tekstur yang saya buat yang terlihat seperti ini:
    Tekstur Ringan (Catatan: Saya menggunakan nilai R, G dan B di sini, tetapi Anda mungkin harus menggunakan saluran alpha di tekstur aktual.)
  5. Menggunakan custom shader, saya membuat permukaan ubin ke layar dan lulus di permukaan pencahayaan sebagai parameter yang diambil sampel untuk nilai "kegelapan" di setiap piksel.


Sekarang, ada beberapa hal yang perlu diperhatikan:

Mengenai Poin 4:

Saya sebenarnya memiliki dua custom shader, satu untuk menggambar lampu ke target render pencahayaan (langkah 4) dan yang lain untuk menggambar target render ubin ke layar menggunakan target render pencahayaan (langkah 5).
Shader yang digunakan pada titik 4 memungkinkan saya untuk menambahkan (apa yang saya sebut) nilai "luminositas". Nilai ini adalah floatyang dikalikan dengan setiap piksel dalam tekstur sebelum ditambahkan ke target render sehingga saya pada dasarnya dapat membuat lampu lebih terang atau lebih gelap.
Pada titik ini, saya juga memperhitungkan nilai "skala" cahaya yang berarti saya dapat memiliki lampu besar atau kecil hanya dengan menggunakan satu tekstur.

Mengenai Poin 5:

Pikirkan target render pencahayaan karena pada dasarnya memiliki nilai untuk setiap piksel dari 0 (hitam) hingga 1 (putih). Shader pada dasarnya mengalikan nilai tersebut dengan nilai RGB untuk piksel dalam target render ubin untuk membuat gambar akhir yang digambar.

Saya juga memiliki beberapa kode di sini di mana saya memberikan (ke shader) nilai untuk digunakan sebagai warna overlay siang / malam. Ini juga dikalikan dengan nilai RGB dan termasuk dalam perhitungan target render pencahayaan.


Sekarang, ini tidak akan memungkinkan Anda untuk melakukan hal-hal seperti memblokir cahaya dari berkeliling benda dan yang lainnya, tetapi setidaknya untuk tujuan saya, itu sederhana dan bekerja dengan baik.

Saya telah menulis posting blog yang lebih rinci di sini dan di sini yang dapat membantu Anda. Saya tidak punya waktu sekarang, tetapi jika Anda mau, saya bisa masuk ke detail lebih lanjut di gamedev.

Oh, dan ini dia lihat di editor peta saya:masukkan deskripsi gambar di sini


Hasilkan dan hapus daftar setiap frame mungkin tidak terlalu mahal?
Gustavo Maciel

@ Gtoknu Tidak membuat perbedaan nyata dalam game saya. Daftar ini hanya menyimpan referensi ke objek yang sudah ada dalam memori sehingga tidak seperti setiap cahaya diciptakan kembali atau apa pun, hanya satu daftar.
Richard Marskell - Drackir

Anda mungkin benar, tidak sepenuhnya, tetapi Anda benar. Tentu saja, Anda tidak membuat objek penuh, tetapi Anda menambahkan pointer ke referensi, penggunaannya masih rendah, tetapi masih memakan. Anda melakukannya dengan cara yang baik, tetapi saya pikir mungkin lebih baik jika Anda meletakkan daftar di luar metode undian, karena melakukan logika dalam pembaruan jauh lebih cepat daripada dalam undian
Gustavo Maciel

@ Gtoknu Tentu, Anda dapat mendeklarasikan daftar di mana pun Anda inginkan, tetapi intinya adalah bahwa lampu dikaitkan dengan ubin. DrawMetode ubin adalah tempat Anda mengetahui apakah ubin memiliki lampu atau tidak. Saya tidak mengulangi semua ubin yang digambar dalam Updatemetode ini sehingga saya akan menambahkan overhead tambahan untuk itu. Juga, XNA mencoba untuk menjamin bahwa Updateakan dipanggil 60 kali per detik sehingga dapat mengorbankan Drawpanggilan untuk ini, yang berarti bahwa kode ini sebenarnya akan dipanggil lebih jarang.
Richard Marskell - Drackir

Semua yang dikatakan, itu adalah titik diperdebatkan karena saya akhirnya memindahkan lampu ke daftar mereka sendiri berdasarkan partisi spasial dan hanya menarik semua lampu di bagian yang memotong layar. Saya tidak membicarakan hal itu di posting saya karena kurangnya waktu, tetapi disebutkan di posting blog kedua yang saya tautkan.
Richard Marskell - Drackir

9

Biasanya, pencahayaan dalam game 2D dilakukan dengan memiliki Peta Normal untuk semua sprite Anda, lalu hitung efek pencahayaan 3D pada sprite 2D Anda. Ini dikenal longgar sebagai "2.5D". Namun saya tidak mau merekomendasikan melakukan hal ini di pertandingan pertama Anda seperti itu kompleks.

Berikut adalah video luar biasa dari seseorang yang telah melakukan ini di XNA: http://www.youtube.com/watch?v=-Q6ISVaM5Ww

Yang mengatakan, mungkin ada cara untuk menipu dan mendapatkan sistem pencahayaan semu yang bisa bekerja dengan berbagai asumsi.


Sudah melihat video ini sebelumnya, +1 karena menyebutkan teknik yang luar biasa.
Gustavo Maciel

Terima kasih atas saran dan tautan videonya. Memang peta tampaknya menjadi solusi. Saya sendiri akan mencoba menggunakan peta pada lapisan atas saya untuk membuat 'celah', atau untuk mengubah efeknya pada objek yang mendasarinya.
Ivaylo Slavov

5

Sulit untuk menyarankan pendekatan jika Anda tidak sepenuhnya spesifik tentang efek yang ingin Anda capai. Detail seperti jika lampu harus terhalang oleh lingkungan atau tidak, apa sudut pandang game Anda, sejauh mana cahaya berinteraksi dengan lingkungan, dll.

Saya akan menjatuhkan dua sen saya. Lihat apakah tutorial ini oleh Catalin Zima berjudul Dynamic 2D Shadows sesuai dengan tagihan Anda. Seperti yang Anda lihat, cahayanya memiliki jari-jari dan tidak melewati rintangan. Anda bisa menghidupkan jari-jari dan warnanya sedikit agar terlihat lebih dekat dengan cahaya obor nyata.

masukkan deskripsi gambar di sini

Dalam hal ini, cahaya bertindak sebagai semacam overlay di atas adegan Anda, tetapi tidak berinteraksi dengannya sampai pada tingkat yang sama seperti dalam contoh John, meskipun ia mempertimbangkan halangan.

Edit

Catalin tautan ke artikel lain yang dia gunakan sebagai referensi, tetapi tautan tersebut rusak. Inilah tautan yang diperbarui .


Terima kasih, saya pikir ini bukan efek yang saya cari, tapi tetap terima kasih sudah berbagi :)
Ivaylo Slavov
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.