Bagaimana saya bisa menerapkan pencahayaan berbasis ubin yang halus?

8

Saya telah mengerjakan permainan ubin 2D dan saya telah menerapkan pencahayaan yang keras:

masukkan deskripsi gambar di sini

Saya ingin sedikit dihaluskan. Saya tidak perlu bayangan atau apa pun, hanya pencahayaan sederhana. Saya ingin terlihat lebih seperti ini:

masukkan deskripsi gambar di sini

Sistem saya saat ini menggunakan level cahaya untuk setiap ubin di dunia dan mereka dihitung ulang, ketika ubin ditempatkan atau dihapus. Saya menggunakan batch.setColor(...)untuk menaungi ubin. Apa cara yang baik untuk mencapai pencahayaan yang halus ini?

Saya tidak ingin menggunakan metode overlay peta cahaya, saya sudah mencobanya dan saya tidak puas dengan hasilnya. Saya ingin dapat mengatur berapa banyak cahaya yang bisa melewati blok. Sebagai contoh, blok tanah harus menyerap sebagian cahaya, tetapi blok kaca seharusnya tidak menghalangi cahaya. Ini tidak mungkin dilakukan dengan metode overlay peta cahaya. UPDATE: Saya salah mengerti apa sebenarnya metode ini. Saya mengerti sekarang. Saya berpikir dengan cara yang salah. Maaf!

ProRed
sumber
Sejujurnya, itu terlihat lebih bergaya dengan pencahayaan yang tajam.
S. Tarık Çetin
Saya tidak terlalu menyukainya, juga agak sulit membedakan ubin latar dan ubin latar dengan gaya ini.
ProRed

Jawaban:

15

Cara sederhana untuk mencapai pencahayaan halus dalam game berbasis ubin, adalah menggambar "lightmap" ke target render, dan kemudian menggambar target render ini di atas adegan Anda saat alpha memadukannya.

Target render peta cahaya Anda akan menjadi ukuran peta ubin Anda, tetapi dalam piksel. Setiap piksel akan mewakili warna terang ubin yang sesuai. Tekstur render ini akan terlihat seperti ini (tekstur kiri atas hitam dan putih):

masukkan deskripsi gambar di sini

Setelah Anda memiliki tekstur peta ringan ini, Anda dapat menggambarnya sebagai hamparan di atas dunia game Anda (terentang). Anda harus menjepitnya dengan benar, sehingga membentang sempurna melampaui ubin Anda di dunia game.

Maka itu adalah masalah alpha memadukan tekstur ini ke dunia gim Anda di libGDX. Untuk berbaur dengan LibGDX (saya pribadi tidak tahu caranya), Anda mungkin harus melihat Gdx.gl.glBlendFuncfungsinya.

jallan
sumber
2
Anda dapat mengontrol pencahayaan seperti yang Anda inginkan dengan sistem ini. Tidak yakin apa yang Anda maksud ketika Anda mengatakan Anda tidak bisa menghalangi cahaya. Juga, tidak sepenuhnya yakin bagaimana Anda berencana untuk memuluskan sistem Anda saat ini, karena Anda benar-benar hanya mewarnai ubin Anda.
jgallant
4
Omong-omong, sistem ini adalah cara Starbound melakukannya.
Qqwy
2
Ini adalah pendekatan yang hebat, dan memungkinkan fleksibilitas di mana diperlukan. Saya menggunakan ini di game berbasis ubin saya di mana saya tidak memiliki akses ke shader, dan itu berfungsi dengan baik!
Tyyppi_77
1
UPDATE : Ini sepertinya cara untuk pergi, saya salah mengerti metode ini dan saya mengerti sekarang sepenuhnya! Saya akan mencoba menerapkan metode ini sekarang dan saya akan menandai ini sebagai jawaban terbaik dan memberi Anda hadiah!
ProRed
2
Jika Anda memiliki pertanyaan lebih lanjut tentang cara melakukannya, jangan ragu untuk bertanya. Saya telah menerapkan ini, dan @ Tyyppi_77 juga baru-baru ini. Saya sudah melakukannya di XNA / Monogame dan Unity. Tyyppi telah melakukannya di SDL.
jgallant
4

cara agnostik mesin untuk melakukannya adalah dengan menggunakan pemetaan cahaya rata-rata. Pertama, Anda perlu membuat peta hitam dan putih sebagai array 2D boolean yang merupakan ukuran dunia di mana blok Benar dan kosong adalah Salah.

Suka Ini (1 berwarna hitam, 0 berwarna putih): peta

Maka Anda perlu membuat array 2D baru yang ukurannya sama dengan array pertama tetapi merupakan array float. Kemudian Anda beralih dari blok hitam (Benar) ke blok hitam dalam array dan rata-rata nilai sampel terdekat (dijelaskan di bawah)

Gambar ini akan membantu: rata-rata

Gambar ini menunjukkan pengambilan sampel (di mana + berarti false dan | berarti benar). apa yang kita lakukan adalah memperlakukan nilai Benar sebagai 1 dan nilai Salah sebagai 0. Kemudian Anda rata-rata angka 9 dan memasukkannya ke bagian array yang benar. CATATAN: Pastikan bahwa saat Anda mengambil sampel tepian, Anda menggunakan memperlakukan nilai luar sebagai peka konteks. Misalnya: bawah tanah peta di luar dunia mungkin 1 dan langit seharusnya 0.

Seharusnya terlihat seperti ini (diambil dari pos lain):akhir

Maka yang harus Anda lakukan adalah mewarnai setiap blok dengan array

rgba(tint,tint,tint,1)

(tint = nilai blok rata-rata saat ini di array kedua dan alpha tidak masalah). Catatan: ini mengasumsikan bahwa rgba pseudo-function mengambil float dari 0-1 bukannya 0-255, jika ya, lakukan saja ini:

rgba(tint*255,tint*255,tint*255,255)

Semoga Ini Masuk akal :) Jika Anda ingin kode, tanyakan!

UDXS
sumber
Fist off terima kasih atas jawaban Anda, tetapi masalahnya saya sudah memiliki pencahayaan yang sulit dalam permainan saya (di sini ). Saya bertanya bagaimana saya bisa mengubah ini agar terlihat lebih mulus ( seperti ini )
ProRed
1

Karena Anda berbicara tentang hal-hal yang menghalangi cahaya, saya berasumsi Anda memiliki beberapa model untuk bagaimana cahaya seharusnya menyebar. Misalnya segala sesuatu tanpa blok di atasnya benar-benar menyala, cahaya menyebar ke semua sel tetangga tetapi kehilangan sejumlah kecerahan.

Anda harus dapat menerapkan aturan-aturan itu dengan cukup mudah di sisi perangkat lunak setidaknya bagian smoothing kemudian hanya masalah melemparkan beberapa shader di peta cahaya yang telah Anda hasilkan.

Metode yang disarankan orang lain dengan overlay peta cahaya adalah sesuatu yang harus Anda lakukan. Tetapi Anda dapat mengubah cara Anda menghasilkan peta cahaya ini. Pada awalnya Anda dapat mengisinya hanya dengan informasi blokir, tetapi kemudian Anda dapat memperbesar dan memperlancarnya menjadi shader misalnya. Manfaat tambahan dari pendekatan peta cahaya adalah bahwa Anda dapat dengan mudah menarik lampu dinamis ke dalam peta cahaya Anda juga untuk menyoroti ledakan atau apa yang Anda miliki dan secara alami akan menyatu dengan seluruh dunia Anda.

Hal-hal campuran aditif ke dalam peta cahaya Anda kemudian gabungkan multiplikasi peta cahaya Anda dengan dunia game.

Saya melakukan ini beberapa waktu lalu yang menggunakan prinsip yang sama. Sistem ini tidak mendukung penurunan cahaya secara berbeda untuk berbagai jenis medan, tetapi setidaknya harus menggambarkan kegunaan overlay peta cahaya.

Nils Ole Timm
sumber
Begitu, jadi saya akan membuat tingkat cahaya dalam bentuk persegi panjang yang persis ukuran ubin yang sesuai dengan target render kedua? Dan bagaimana saya melicinkannya?
ProRed
Anda dapat membiarkan GPU menanganinya dengan downsampling, karena ketika merendernya hanya akan menginterpolasi secara linear untuk Anda. Jika itu tidak cukup baik, Anda dapat menjalankan semacam kabur di shader. Anda juga dapat mempertimbangkan untuk membuat granularitas yang lebih halus daripada resolusi ubin jika Anda ingin menggambar secara berbeda tergantung pada ubin yang berdekatan. Pada dasarnya bagian yang sulit datang dengan aturan spesifik yang Anda inginkan untuk area apa yang harus menyala berapa. Jika Anda menuliskan aturan-aturan itu, Anda biasanya akan menemukan cara yang cukup mudah untuk melakukannya.
Nils Ole Timm
1

Cukup mudah untuk sebuah obor: menggunakan shader piksel khusus Anda menghitung jarak antara masing-masing fragmen dan obor; Anda kemudian dapat menghitung dari mana ubin padat pertama yang menghalangi cahaya yang berasal dari obor. Anda kemudian menghitung jarak di mana cahaya tidak terhalang, kalikan dengan sesuatu <1 sehingga obor tidak menyalakan matahari, kurangi dari jarak total, dan ulangi untuk sisa jarak (di mana cahaya terhalang oleh pada paling tidak satu ubin) dengan nilai gandakan jauh lebih kecil ... Saya tahu cara melakukan matematika ini dan tidak terlalu rumit untuk diterapkan dalam OpenGL.

EDIT: untuk sumber cahaya sederhana dengan titik tengah tertentu, metode saya sangat sederhana. Namun saya tidak bekerja dengan sinar matahari, tetapi sementara peta alfa bekerja dengan sangat baik untuk sinar matahari, itu TIDAK akan menjadi ide yang baik untuk obor, mengingat bahwa itu berpotensi objek bergerak, dan membuat peta baru setiap frame tidak menyenangkan suatu pengalaman hidup. Solusi terbaik menurut saya adalah campuran: penghitungan jarak untuk lampu tertentu yang sebenarnya adalah objek dalam permainan, shader terpisah yang baru saja Anda lempar di atas peta alfa yang Anda buat secara prosedural dengan menggunakan teknik yang disebutkan di atas: tekstur semua ubin Alpha dari bayangan keras Anda, seperti banyak kotak, dan dipusingkan dengan teknik untuk menghaluskannya.

Paul Boursin
sumber
0

Apakah rendering Anda menggunakan warna titik (atau dapatkah Anda mengubahnya)?

Dengan asumsi setiap blok adalah kotak 4-simpul, yang akan memberi Anda beberapa opsi, misalnya:

Jika algoritma pencahayaan Anda saat ini memberi Anda nilai cahaya per blok, Anda bisa mengubahnya untuk memberi Anda nilai per titik. Bergantian, di setiap titik Anda bisa meratakan warna terang dari blok saat ini ditambah tiga tetangganya. Solusi mana pun tidak mahal.

Pemrogram Game Kronis
sumber