Di Minecraft saat Anda melihat air, semakin dalam Anda melihat semakin gelap. Adakah yang tahu cara membuat kode seperti itu?
Minecraft dengan efek
game serupa tanpa efek
Di Minecraft saat Anda melihat air, semakin dalam Anda melihat semakin gelap. Adakah yang tahu cara membuat kode seperti itu?
Minecraft dengan efek
game serupa tanpa efek
Jawaban:
Pada dasarnya ada dua pendekatan berbeda untuk penerangan air berdasarkan kedalaman:
Minecraft menggunakan pencahayaan berbasis voxel, yang bekerja dengan menyebarkan cahaya ke kubus yang berdekatan, menurunkan kecerahan tergantung pada jenis blok. Lautan gelap adalah efek samping dari sistem ini.
Air memblokir sinar matahari dan mengurangi cahaya sebanyak 3 level per blok (bukan level 1 standar), yang berarti kecerahan di lautan untuk setiap jarak dari permukaan adalah:
0 (surface): 15 (direct sunlight)
1: 12
2: 9
3: 6
4: 3
5 and below: 0 (darkness)
Sumber: Minecraft Wiki - Light
Dalam permainan dengan model pencahayaan tradisional, efek ini dapat dibuat dengan mengukur jumlah air yang ada di antara sumber cahaya dan dasar laut. Cahaya kemudian memudar berdasarkan jarak ini. Ada beberapa metode untuk melakukan ini:
Jika Anda memiliki permukaan yang rata, Anda dapat dengan mudah menghitung jarak yang ditempuh cahaya di dalam air jika Anda melewatkan permukaan normal dari badan air dan titik produk normal ini dan posisi permukaan ke dalam shader geometri.
Jarak air efektif adalah
dimana letak verteks dan merupakan sudut antara arah cahaya di bawah permukaan dan permukaan air normal menuju badan air.
Saat matahari terbenam, hanya mencapai sedikit kurang dari 50 ° karena cahaya dibiaskan saat memasuki air.
Berikut adalah posting blog dengan penjelasan yang baik: Kamera Digital: Refleksi Internal Total
Posting lain dengan rincian lebih lanjut: Kamera Digital: Hukum Pembiasan Snell
Jika Anda menggunakan peta ketinggian pada permukaan yang sejajar dengan air, jadilah . Faktor yang tepat sama dengan 1 jika matahari langsung di atas permukaan air.
Dengan cahaya titik, Anda harus menghitung untuk setiap titik berdasarkan posisi relatif ke sumber cahaya.
Dengan ketinggian air tetap atau arah cahaya tetap, bagian dari persamaan adalah konstan dan tidak boleh dihitung dalam shader karena alasan kinerja.
Jika Anda merender permukaan air ke peta kedalaman yang terpisah (seperti yang terlihat dari sumber cahaya), Anda dapat menggunakan tekstur kedalaman itu untuk menghitung jarak yang ditempuh cahaya di dalam air sebelum mengenai permukaan.
Untuk melakukan ini, Anda memproyeksikan setiap simpul ke proyeksi tampilan sumber cahaya di shader vertex dan melakukan pencarian tekstur dalam pixel shader.
Jika permukaannya relatif rata, Anda harus menggunakan sumber cahaya yang dibiaskan untuk hasil yang lebih baik.
* Anda dapat menentukan jumlah air di depan permukaan padat terdekat dengan menghitung kedalaman dari POV cahaya sebagai berikut:
Tekstur hasil sekarang berisi jumlah air di depan cahaya dalam ruang tampilan cahaya, sehingga nilainya harus diubah kembali sebelum Anda menggunakannya. Metode ini berfungsi untuk menghitung cahaya arah (minus refraksi), tetapi akan menyebabkan cahaya ambient yang salah jika permukaannya sangat tidak teratur dan ada banyak udara di antara badan air yang mempengaruhi fragmen yang sama.
Pro dan kontra sama dengan pemetaan bayangan normal, kecuali bahwa Anda memerlukan satu buffer lagi saat menghitung kedalaman dan kinerjanya lebih buruk karena Anda harus menggambar lebih banyak geometri.
Ray tracing sejauh ini adalah yang paling akurat tetapi juga solusi paling mahal untuk menghasilkan volume transparan. Ada dua cara untuk melakukan ini: 1. Menelusuri dari dasar samudera menuju permukaan dan 2. Menelusuri dari sumber cahaya menuju air. Diperlukan beberapa sinar untuk setiap titik di lantai untuk menghitung kecerahan.
Ada beberapa hal lagi yang perlu diperhatikan saat memberikan air:
Cahaya dalam air tersebar lagi saat bepergian ke pengamat, jadi Anda harus membaurkannya ke warna solid.
Jika pengamat tenggelam , Anda bisa membuat kabut berdasarkan hasil akhir buffer kedalaman. Warna kabut, tetapi kepadatannya tidak akan berubah dengan jarak pengamat dari permukaan! (Minecraft hanya menggunakan bagian dari efek ini.)
Jika pengamat melihat air dari atas , Anda perlu menghitung kabut berdasarkan perbedaan kedalaman antara permukaan dan geometri di bawah air. Warna kabut akan menjadi sedikit lebih gelap dengan perbedaan kedalaman yang lebih besar, tetapi hanya akan berubah ke titik di mana kabut sepenuhnya buram.
Warna kabut juga harus bergantung pada arah tampilan untuk setiap piksel, sehingga sedikit lebih gelap saat melihat ke bawah dalam kedua kasus.
Jika Anda menggunakan Tekstur 3D ubin mulus alih-alih decal untuk kaustik palsu, Anda dapat menghindari peregangan pada permukaan vertikal. Kekuatan cahaya yang tersebar di dekat permukaan bervariasi dalam tiga dimensi, jadi menggunakan 2D-Texture biasanya menghasilkan peregangan di suatu tempat dalam pemandangan. Anda dapat memodelkan perubahan sudut cahaya dengan memproyeksikan posisi titik lantai ke sistem koordinat yang berbeda.
Kemungkinan lain adalah untuk menghitung kerapatan cahaya berdasarkan posisi permukaan dalam sistem koordinat cahaya, meskipun itu kemungkinan besar akan membutuhkan beberapa kinerja.
Kaustik harus memudar lebih cepat dari cahaya difus dengan meningkatnya kedalaman.
Warna tersebar secara berbeda, sehingga warna terang harus berubah dengan meningkatnya kedalaman. Ini juga mencegah tepi tiba-tiba di mana, misalnya, pantai memotong permukaan air.
Karena pembiasan, cahaya menghantam dasar lautan jauh lebih curam daripada biasanya. The Wikipedia artikel tentang hukum Snell memiliki formula untuk sudut dan vektor.
Saya percaya bahwa efek pencahayaan langit di Minecraft lurus ke bawah - segala sesuatunya diarsir oleh apa yang ada di atas mereka di mana pun matahari berada. Kemudian pencahayaan lokal dari obor, dll diterapkan dengan efek dropoff - semakin jauh dari sumber cahaya, semakin sedikit cahaya yang didapat dari kubus.
Jika dilakukan dengan cara ini, setiap lapisan air akan secara kumulatif membayangi lapisan di bawahnya, sehingga masing-masing menjadi semakin gelap. Dedaunan pohon memberikan keteduhan seperti ini, namun tidak kumulatif. Anda mendapatkan naungan yang sama di bawah pohon apakah itu 1 atau 100 kubus dedaunan.
Satu petunjuk bahwa ini adalah metode yang digunakan adalah bahwa air tidak menjadi lebih gelap ketika semakin jauh dari penonton - hanya saat Anda turun. Ya, efek kabut memang menendang di kejauhan, tetapi tidak efek air gelap.
Jadi rumus dasar untuk menghitung pencahayaan akan menjadi seperti ini dalam pseudo-code ...
light_on_cube = 1.0
for each cube above target cube, from lowest to highest {
if cube being examined is tree foliage
light_on_cube = 0.5
else if cube being examined is water
light_on_cube = light_on_cube - 0.1
else if cube being examined is solid
light_on_cube = 0
}
Ini tidak sempurna untuk menghitung pencahayaan di bawah gantung atau di gua, karena akan gelap gulita di bawah gantung menggunakan metode ini. Tetapi orang dapat menambahkan kedua sumber cahaya lokal (obor, api, dll.) Serta memperlakukan balok yang menyala sebagai sumber cahaya. Sesuatu seperti ini mungkin melakukannya ...
Idenya di sini adalah bahwa jika sebuah kubus dinyalakan oleh matahari atau obor, kubus di sebelahnya juga akan dinyalakan dengan cara tertentu. Dan semakin jauh Anda dari kubus yang menyala itu, semakin sedikit cahaya yang ada. Ini semacam cara kludge untuk memperkirakan pencahayaan difus tapi saya pikir (?) Itu akan berhasil.
Mungkin saya salah paham pertanyaannya, tetapi mengapa Anda tidak bisa mengubah warna balok tergantung kedalamannya?
Jika Anda memiliki kedalaman d (dalam blok, mulai dari 0) maka persamaan yang masuk akal untuk kecerahan adalah:
L = (1- m ) e - kd + m
Kode: L = (1.0 - m) * exp(-k * d) + m;
k mengontrol seberapa cepat ia menjadi lebih gelap (lebih tinggi = lebih cepat). Nilai yang masuk akal adalah 0,5.
m adalah kecerahan minimum yang Anda inginkan.
L bervariasi dari 0 hingga 1.
Jika Anda tidak tahu cara mengubah warna blok di API grafik apa pun yang Anda gunakan, silakan tanyakan itu sebagai pertanyaan terpisah (nyatakan API apa yang Anda gunakan, dan apakah Anda menggunakan shader atau tidak).
e^-kd
bit hanya sebuah peluruhan eksponensial, yang merupakan fungsi standar untuk hal-hal yang secara bertahap cenderung menuju nol atas beberapa nilai (kedalaman). Penggandaan dengan (1-m)
dan penambahan m
hanya untuk skala dan mengimbangi pembusukan sehingga berakhir minimal m
tetapi masih dimulai pada 1
. en.wikipedia.org/wiki/Exponential_decay