Membuat Pixel Nebula Menggunakan Noise dan Median Cut

Saya ingin nebula di game saya The Last Boundary . Mereka terlihat luar biasa dan ruang tanpa mereka bukanlah ruang, tetapi hanya piksel putih yang tersebar di latar belakang. Tapi karena saya membuat game dengan gaya "pixel art", saya perlu membuat perpustakaan noise saya menghasilkan gambar pixelated.

Berikut ini beberapa contohnya:



Lebih banyak contoh





Dalam contoh warna tunggal, 8 warna digunakan, dan yang lain, 16 warna. Pada artikel ini, saya akan berbicara tentang bagaimana saya membuat nebula pixelated untuk The Last Boundary.

Ketika kami bekerja dengan pustaka suara, seperti LibNoise , tidak peduli mesin apa yang Anda gunakan (atau tulis sendiri), nilainya biasanya didistribusikan dalam kisaran dari -1 hingga 1 . Secara teoritis lebih mungkin bahwa noise 2D akan berada dalam kisaran dari -0.7 hingga 0.7 , tetapi beberapa implementasi skala hasilnya, menerjemahkannya ke dalam interval dari -1 ke 1 . Untuk bekerja dengan tekstur 2D, biasanya dikonversi ke interval dari 0 ke 1 , dan kemudian RGB(255,255,255) dalam kisaran dari RGB(0,0,0) ke RGB(255,255,255) .


Perlin noise dihasilkan dari koordinat x,y dari setiap piksel yang diskalakan ke 0.3f

Kemudian Anda dapat menggunakan gerakan Brownian fraksional untuk memberikan kesan kemegahan awan pada gambar.


Perlin noise menjadi sasaran gerakan Brown fraksional dengan 8 oktaf, frekuensi 0.01 , keteraturan 0.5 dan lacunaritas 2.0 .

Saya perhatikan bahwa ada banyak implementasi salah Perlin noise, simplex noise, dan fraksional Brownian motion (fBm) di Internet. Tampaknya ada banyak kebingungan tentang apa itu apa. Pastikan Anda menggunakan implementasi yang benar, karena jika Anda ingin membuat rantai yang dijelaskan di atas, maka dalam kasus implementasi yang salah, Anda mungkin tidak mendapatkan hasil yang diperlukan.

Mari kita bayangkan bahwa kita ingin menciptakan efek asap, yaitu solusi seperti itu cocok untuk kita. Tapi permainan pixel art kami akan terlihat aneh jika sejumlah warna baru muncul di dalamnya dari RGB(0,0,0) ke RGB(255,255,255) . Tiba-tiba, 255 nilai abu-abu baru akan muncul dalam permainan.

Kita perlu mengubahnya menjadi sejumlah warna. Itu yang akan kita lakukan nanti. Sementara itu ...

Hasilkan nebula acak


Saya ulangi untuk tutorial yang sudah jadi tentang membuat nebula acak, tetapi menambahkan beberapa langkah saya dan menerapkan pustaka suara saya sendiri. Saya menulisnya beberapa tahun yang lalu karena saya ingin mendapatkan pemahaman yang baik tentang kebisingan Perlin dan bagaimana Anda dapat menggunakannya bersama dengan konsep lain untuk membuat tekstur dan sejenisnya.

Mungkin Anda dapat mengulangi setelah saya langkah demi langkah atau Anda harus membuat tambahan pada kode yang akan mempengaruhi kebisingan Anda. Saya akan menjelaskan semuanya kecuali generasi kebisingan awal dan fBm sehingga Anda dapat menulis kode sendiri; Saya pikir dapat diasumsikan bahwa Anda sudah memiliki kemampuan untuk menghasilkan noise dan fBm.

Untuk memulai, saya akan menunjukkan hasil pembuatan nebula:


Hasil jadi

Penting untuk dicatat bahwa itu belum pixelated. Ini memiliki berbagai macam warna dengan langit berbintang pixelated. Nebula yang akan kita pixelate nanti.

Hal pertama yang harus dilakukan adalah menghasilkan lima tekstur berbeda: Merah, Hijau, Biru, Alpha dan Topeng. Tekstur Merah, Hijau, dan Biru diperlukan untuk saluran warna akhir yang sesuai. Bahkan, saya hanya menghasilkan satu atau dua saluran warna, karena ternyata menggunakan ketiganya menghasilkan nebula yang sangat berwarna yang terlihat jelek. Setiap warna tunggal atau kombinasi dua warna akan berhasil.

Saluran Alpha penting karena tergantung padanya apakah bintang-bintang yang lebih rendah akan bersinar melalui nebula. Saya akan menggambarkan ini dengan menampilkan saluran alpha dari contoh yang ditunjukkan di atas.


Saluran alpha siap dari contoh kita

Semakin putih area, semakin dekat nilainya ke 1.0 , yang memberi kita nilai alpha 255 . Semakin gelap area, semakin transparan. Jika Anda melihat contoh, Anda dapat melihat bahwa area hitam sesuai dengan area di mana langit berbintang terlihat.


Contoh langit berbintang

Ini bukan bintang yang sama seperti pada contoh, karena mereka dihasilkan secara acak di setiap tangkapan layar. Saya harap ini tidak mencegah Anda dari memahami bagaimana nebula dihasilkan.

Pustaka derau saya terdiri dari beberapa modul, mengikuti contoh Lib Noise . Segala sesuatu di perpustakaan ini adalah "modul" yang dapat dirantai bersama. Beberapa modul menghasilkan nilai baru (Modul Perlin, Nilai Konstan), yang lain menghubungkannya (Multiply, Tambah), dan beberapa hanya melakukan operasi pada nilai (Lerp, Clamp).

Saluran warna


Tidak masalah jika kita bekerja dengan satu, dua atau tiga warna - saluran Merah, Hijau dan Biru dihasilkan dengan cara yang sama; Saya hanya menggunakan nilai seed yang berbeda untuk mereka. Nilai seed saya tergantung pada waktu sistem saat ini.

Di bawah mereka semua disajikan dalam skala abu-abu, tetapi secara teoritis mereka hanyalah nilai untuk salah satu dari tiga saluran. Grayscale ada di sini hanya untuk menggambarkan hasilnya.

1. Kebisingan Perlin


Seperti di atas, kebisingan Perlin akan menjadi titik awal. Jika mau, Anda bisa menggunakan simplex noise, sepertinya implementasi 2D-nya bukan milik Ken Perlin, tapi saya bisa saja salah. Dari sudut pandang matematika, noise simplex menggunakan lebih sedikit instruksi, sehingga generasi nebula yang sama akan lebih cepat. Karena ia menggunakan simpleks alih-alih kisi-kisi, ia menciptakan suara yang sedikit lebih indah, tetapi kami tidak akan banyak menggunakannya, jadi ini tidak terlalu penting.

Kode sebenarnya tidak ditunjukkan di bawah ini, karena dalam sumber nyata nilai x,y diubah oleh fBm pada langkah 3. Ini hanya koordinat x,y dari gambar yang dikalikan dengan faktor penskalaan statis.


Perlin noise dihasilkan dari koordinat x,y dari setiap piksel yang diskalakan ke 0.3f . Yaitu PixelValue = PerlinNoise(x * 0.3f, y * 0.3f)

Nilai yang dibuat oleh noise Perlin kira-kira berkisar antara -1 hingga 1 , jadi untuk membuat gambar skala abu-abu seperti ditunjukkan di atas, kami mengonversinya ke interval dari 0 hingga 1 . Saya menguji cakupan nilai sehingga konversi menghasilkan kontras terbesar (nilai terendah sesuai dengan 0 , terbesar - 1 ).

2. Multiplikasi


Modul selanjutnya yang digunakan mengalikan kebisingan yang dihasilkan dengan 5 . Ini bisa dianggap penyesuaian kontras. Nilai negatif lebih gelap, nilai positif lebih ringan.

Saya tidak punya apa-apa untuk ditampilkan di sini, karena dalam proses mengubah nilai dari interval dari -5 ke 5 ke interval dari 0 ke 1 hasilnya tidak berubah.

3. Gerakan Brown Pecahan (fBM)


Tahap ini mengubah suara menjadi apa yang oleh banyak orang dianggap sebagai "efek kebisingan" nyata. Di sini kita mengeksekusi oktaf dari sampel yang semakin kecil dari fungsi noise (dalam kasus kami, fungsinya adalah perlin(x,y) ) untuk menambahkan fluffiness.


Gerakan Pecahan Brown dari kebisingan Perlin ditunjukkan di atas. 8 oktaf, frekuensi .01f , keteraturan .5f dan 2.5f

Anda sudah bisa melihat asal sesuatu yang menarik. Gambar yang ditunjukkan di atas tidak dihasilkan oleh penskalaan koordinat x,y dari piksel, fBM melakukan ini. Sekali lagi, nilai-nilai ini secara terbalik dikonversi ke interval dari 0 ke 1 ke interval yang mungkin dari -5 ke 5 .

4. Pembatasan (Penjepit)


Sekarang saya akan membatasi nilai ke kisaran -1 hingga 1 . Apa pun di luar interval ini akan sepenuhnya dibuang.


FBm yang sama, terbatas pada -1 hingga 1

Tugas operasi ini adalah untuk mengkonversi nilai ke interval yang lebih pendek sambil menciptakan gradien yang lebih tajam dan meningkatkan area dalam warna putih atau hitam penuh. Area kosong atau kosong ini penting untuk efek nebula, yang akan kita bahas nanti. Jika kita tidak dikalikan 5 pada awalnya, maka penjepit tidak akan mengubah apa pun.

5. Tambahkan 1


Sekarang kita mengambil nilai dari klem dan menambahkan 1. Untuk itu, dengan demikian, kita mentransfer nilai ke interval dari 0 ke 2 . Setelah konversi, hasilnya akan terlihat sama seperti sebelumnya.

6. Bagi dengan 2


Anda mungkin tahu apa yang akan terjadi ketika saya membagi hasilnya dengan 2 (kalikan dengan .5 ). Pada gambar, tidak ada yang akan berubah lagi.

Langkah 5 dan 6 mengonversi nilai ke rentang dari 0 hingga 1 .

7. Buat tekstur distorsi


Langkah selanjutnya adalah membuat tekstur distorsi. Saya akan melakukan ini dengan Perlin noise (dengan nilai seed baru)> kalikan dengan 4> jalankan fBm. Dalam hal ini, fBm menggunakan 5 oktaf, frekuensi 0.025 , keteraturan 0.5 dan lacunaritas 1.5 .


Tekstur distorsi

Tekstur ini diperlukan untuk membuat detail lebih banyak daripada pada tekstur nebula yang ada. Nebula adalah awan bergelombang yang agak besar, dan tekstur ini akan membuat sedikit perubahan padanya. Melalui itu, sifat grid dari suara Perlin akan mulai muncul.

8. Mengimbangi tekstur warna menggunakan tekstur offset


Selanjutnya saya akan mengambil dua tekstur ini dan menggunakan satu untuk mengimbangi koordinat yang lain dengan faktor. Dalam kasus kami, kombinasi terlihat seperti ini:


Hasil bias

Tekstur distorsi digunakan untuk mengubah koordinat x,y kita cari dalam data noise sumber.

Ingat bahwa gambar yang ditunjukkan di atas hanya untuk tujuan ilustrasi. Pada setiap tahap, kami sebenarnya hanya memiliki fungsi noise. Kami memberikan nilai x,y , dan mengembalikan angka. Pada tahap tertentu, interval angka ini mungkin berbeda, tetapi di atas kami mengonversinya kembali menjadi skala abu-abu untuk membuat gambar. Gambar dibuat dengan menggunakan setiap koordinat x,y dari gambar sebagai x,y , yang ditransmisikan oleh fungsi noise.

Yaitu, ketika kita mengatakan:

Beri saya nilai untuk piksel sudut kiri atas dengan X = 0 dan Y = 0

fungsi mengembalikan kita nomor. Jika kita meminta Perlin untuk ini, kita tahu bahwa itu akan antara -1 dan 1 , jika, seperti di atas, kita menerapkan penjepit, penjumlahan dan perkalian, kita mendapatkan nilai antara 0 dan 1 .

Setelah memahami ini, kita belajar bahwa fungsi gangguan distorsi menciptakan nilai dalam kisaran dari -1 hingga 1 . Karena itu, untuk melakukan bias ketika kita mengatakan:

Beri saya nilai untuk piksel di sudut kiri atas dengan piksel X = 0 dan Y = 0

modul offset pertama-tama meminta fungsi offset untuk koordinat x,y . Hasil ini adalah antara -1 dan 1 (seperti di atas). Kemudian dikalikan dengan 40 (ini adalah koefisien yang saya pilih). Hasilnya akan menjadi nilai antara -40 dan 40 .

Kemudian kita mengambil nilai ini dan menambahkannya ke koordinat ke x,y yang kita cari, dan menggunakan hasil ini untuk mencari tekstur warna. Kami memotong nilai negatif dengan clamp ke 0, karena tidak mungkin untuk mencari koordinat x,y negatif dalam fungsi noise (setidaknya di perpustakaan noise saya).

Secara umum, ini terlihat seperti ini:

 ColourFunction(x,y) =     0  1 DisplaceFunction(x,y) =     -1  1 DoDisplace(x,y) = { v = DisplaceFunction(x,y) * factor clamp(v,0,40) x = x + v; y = y + v; if x < 0 then x = 0 if y < 0 then y = 0 return ColourFunction(x,y) } 

Saya harap Anda mengerti ini. Faktanya, kita tidak melihat x,y kita berada, tetapi pada offset. Dan karena besarnya juga merupakan gradien yang halus, ia dengan lancar bergeser.

Ada cara lain untuk melakukan offset. Perpustakaan kebisingan saya memiliki modul yang menciptakan perpindahan spiral. Dapat digunakan untuk menggambar tekstur, secara bertahap menurun ke beberapa titik. Berikut ini sebuah contoh .

Itu saja. Kami mengulangi operasi di atas tiga kali, menggunakan nilai seed baru untuk setiap saluran warna. Anda dapat membuat satu atau dua saluran. Saya tidak berpikir layak membuat yang ketiga.

Saluran alfa


Saluran alfa dibuat dengan cara yang sama seperti saluran warna:

  1. Kami mulai dengan suara Perlin
  2. Kalikan dengan 5
  3. fBM dengan 8 oktaf, frekuensi 0.005 , keteraturan 0.5 dan lacunaritas 2.5
  4. Kami membatasi hasil menggunakan Clamp ke interval dari -1 ke 1 , tambahkan 1 , bagi dengan 2 (mis., Kami menggeser interval dari -1 ke 1 ke interval dari 0 ke 1 .
  5. Kami menggeser hasilnya dengan jumlah kecil ke arah negatif. Saya mengimbangi dengan 0.4 . Berkat ini, semuanya menjadi sedikit lebih gelap.
  6. Kami membatasi hasil pada interval dari 0 hingga 1 . Karena kami memindahkan semuanya, membuatnya sedikit lebih gelap, pada kenyataannya, kami menciptakan lebih banyak area dengan 0 , dan beberapa area masuk ke nilai negatif.

Hasilnya adalah tekstur saluran alpha.


Tekstur alfa

Seperti yang saya katakan, area hitam akan transparan, dan area putih akan buram.

Topeng saluran


Ini adalah tekstur terakhir yang digunakan untuk membuat bayangan overlay di atas segalanya. Itu dimulai seperti semua tekstur lainnya:

  1. Perlin kebisingan
  2. Kalikan dengan 5
  3. Kami melakukan fBm, 5 oktaf, frekuensi 0.01 , keteraturan 0.1 , lacunaritas 0.1 . Keteraturan adalah kecil, sehingga awannya kurang padat
  4. Lakukan pergeseran interval dari -1 ke 1 ke interval dari 0 ke 1

Tapi kami membuat dua tekstur seperti itu:


Topeng a


Topeng B

Kami memaparkan dua tekstur ini ke apa yang saya sebut modul Pilih . Bahkan, kami menggunakan nilai dari modul A atau modul B. Pilihannya tergantung pada nilai modul C. Ini membutuhkan dua nilai lebih - Pilih Point dan Falloff .

Jika nilai pada titik x,y modul C lebih besar dari atau sama dengan SelectPoint , maka kami menggunakan nilai pada titik x,y modul B. Jika nilainya kurang dari atau sama dengan SelectPoint - Falloff , maka kami menggunakan nilai pada x,y modul A.

Jika berada di antara SelectPoint - Falloff dan SelectPoint , maka kami melakukan interpolasi linier antara nilai x,y dari modul A dan modul B.

 float select(x, y, moduleA, moduleB, moduleC, selectPoint, falloff) { float s = moduleC(x,y); if(s >= selectPoint) return moduleB(x,y); else if(s <= selectPoint - falloff) return moduleA(x,y); else { float a = moduleA(x,y); float b = moduleB(x,y); return lerp(a, b, (1.0 / ((selectPoint - (selectPoint-falloff)) / (selectPoint - s))); } } 

Dalam kasus kami, modul A adalah modul Konstan dengan nilai 0 . Modul B adalah tekstur pertama dari mask A, dan Selector (modul C) adalah mask kedua dari B. SelectPoint akan menjadi 0.4 , dan Falloff akan menjadi 0.1 . Sebagai hasilnya, kita mendapatkan:


Topeng pamungkas

Dengan menambah atau mengurangi SelectPoint , kami mengurangi atau menambah jumlah hitam dalam topeng. Dengan menambah atau mengurangi falloff , kami menambah atau mengurangi tepi lunak topeng. Alih-alih salah satu topeng, saya bisa menggunakan modul Constant dengan nilai 1 , tapi saya ingin menambahkan sedikit keacakan ke area "membuka kedok".

Campur saluran warna dan topeng


Sekarang kita perlu menerapkan masker ke masing-masing saluran warna. Ini dilakukan dengan menggunakan modul Blending . Ini menggabungkan persentase nilai dari dua modul sehingga jumlah nilai adalah 100%.

Yaitu, kita dapat mengambil 50% dari nilai dalam x,y modul A dan 50% dari nilai dalam x,y modul B. Atau 75% dan 25%, dll. Persentase yang kita ambil dari masing-masing modul tergantung pada modul lain - modul C. Jika nilai dalam x,y modul C adalah 0 , maka kita akan mengambil 100% dari modul A dan 0% dari modul B. Jika itu adalah 1 , maka kita mengambil nilai terbalik.

Gabungkan untuk setiap tekstur warna.

  • Modul A - Nilai Konstan 0
  • Modul B adalah saluran warna yang telah kita lihat
  • Modul C - mask hasil

Ini berarti bahwa noise saluran warna akan ditampilkan hanya di mana topeng memiliki nilai di atas 0 (area lebih dekat ke putih), dan besarnya visibilitas mereka tergantung pada nilai topeng.

Inilah hasil untuk contoh kita:


Hasil akhir

Bandingkan ini dengan aslinya sebelum menerapkan pencampuran dengan masker.


Sebelum dicampur dengan masker

Mungkin contoh ini tidak terlalu jelas, tetapi karena kebetulan sulit untuk secara khusus memilih contoh yang baik. Efek topeng adalah membuat area yang lebih gelap. Tentu saja, Anda dapat menyesuaikan topeng agar lebih jelas.

Penting di sini bahwa topeng yang sama diterapkan ke seluruh saluran warna, yaitu area yang sama muncul dalam bayangan.

Kami menggabungkan semuanya bersama


Contoh selesai awal kami:


Contoh siap

Ini menggunakan saluran Merah, Hijau, dan Alpha:


Saluran merah


Saluran hijau


Saluran alfa

Dan kemudian kita hanya meletakkannya di atas langit berbintang kita.

Semuanya sekarang terlihat cukup bagus, tetapi tidak terlalu cocok untuk game pixel art. Kita perlu mengurangi jumlah warna ...

Median dipotong


Bagian artikel ini dapat diterapkan untuk apa saja. Katakanlah Anda menghasilkan tekstur marmer dan ingin mengurangi jumlah warna. Di sinilah algoritma median cut berguna. Kami akan menggunakannya untuk mengurangi jumlah warna dalam nebula yang ditunjukkan di atas.

Ini terjadi sebelum ditumpangkan di langit berbintang. Jumlah warna sepenuhnya berubah-ubah.

Algoritma Median Cut seperti yang dijelaskan dalam Wikipedia:

Misalkan kita memiliki gambar dengan jumlah piksel sembarang dan kami ingin menghasilkan palet 16 warna. Masukkan semua piksel dalam gambar (mis. Nilai RGB-nya ) di tempat sampah . Cari tahu saluran warna mana (merah, hijau atau biru) di antara semua piksel dalam keranjang yang memiliki rentang nilai terbesar, lalu urutkan piksel sesuai dengan nilai saluran ini. Misalnya, jika saluran biru memiliki rentang nilai terbesar, maka piksel dengan nilai RGB (32, 8, 16) lebih kecil daripada piksel dengan nilai RGB (1, 2, 24), karena 16 <24. Setelah menyortir keranjang, tempatkan bagian atas piksel tersebut ke dalam keranjang baru. (Langkah ini memberi nama pada algoritma median cut; keranjang dibagi dua oleh median dari daftar piksel.) Ulangi proses untuk kedua keranjang, yang akan memberi kita 4 keranjang, kemudian ulangi untuk semua 4 keranjang, dapatkan 8 keranjang, kemudian ulangi untuk 8 keranjang, kita dapatkan 16 keranjang. Kami rata-rata piksel di masing-masing keranjang dan mendapatkan palet 16 warna. Karena jumlah keranjang berlipat ganda pada setiap iterasi, algoritma hanya dapat menghasilkan palet seperti itu, jumlah warna yang merupakan kekuatan dua . Misalnya, untuk menghasilkan palet 12-warna, Anda harus terlebih dahulu membuat palet 16-warna, dan kemudian menggabungkan beberapa warna.

Sumber: https://en.wikipedia.org/wiki/Median_cut

Penjelasan ini bagi saya agak buruk dan tidak terlalu berguna. Saat mengimplementasikan algoritme, gambar yang jelek dihasilkan dengan cara ini. Saya menerapkannya dengan beberapa perubahan:

  1. Kami menyimpan boxes kontainer bersama dengan nilai yang menunjukkan interval (lebih lanjut tentang ini di bawah ini). box hanya menyimpan sejumlah piksel dinamis dari gambar asli.
  2. Tambahkan semua piksel dari gambar asli sebagai pertama dan gunakan interval 0
  3. Sementara jumlah total kurang dari jumlah warna yang diperlukan, kami melanjutkan langkah-langkah berikut.
  4. Jika nilai interval adalah 0 , maka untuk setiap kotak saat ini kami menentukan saluran warna utama dari box ini, dan kemudian mengurutkan piksel dalam box ini dengan warna ini. β€” Red, Green, Blue Alpha, . , redRange = Max(Red) - Min(Red) . , .
  5. box boxes . , box .
  6. , 4 5 box , boxes . , , , . , , .
  7. box ( == ) boxes . 0 ( ). , , , β€” . .

Ketika kami mencapai jumlah kotak sama dengan jumlah warna yang diinginkan, kami cukup rata-rata semua piksel di setiap kotak untuk menentukan elemen palet yang paling cocok dengan warna-warna ini. Saya hanya menggunakan jarak Euclidean, tetapi ada solusi persepsi yang dapat melakukan ini dengan lebih baik.

Berikut adalah gambar yang akan menjelaskan semuanya dengan lebih jelas. Untuk demonstrasi, saya hanya menggunakan RGB, karena alpha sulit ditampilkan.


Mari kita terapkan metode ini pada contoh gambar kita.


Asli


Median Potong hingga 16 warna

Saya menemukan bahwa ketika menggunakan dua saluran warna, efek yang baik diperoleh dengan 16 warna. Namun perlu diingat bahwa di sini kita menggunakan saluran alfa, yang juga terlibat dalam menghitung jarak antar warna. Jadi jika Anda tidak peduli dengan transparansi, maka Anda dapat menggunakan lebih sedikit warna. Karena potongan median saya, tidak seperti contoh Wikipedia, dapat menggunakan jumlah warna sewenang-wenang (dan bukan hanya kekuatan dua warna), Anda dapat menyesuaikannya agar sesuai dengan kebutuhan Anda.


Dari 16 hingga 2 warna.

Kami memilih warna dari masing-masing warna box, cukup dengan rata-rata semua nilai. Namun, ini bukan satu-satunya cara. Anda mungkin telah memperhatikan bahwa hasil kami dibandingkan dengan aslinya tidak terlalu cerah. Jika Anda membutuhkannya, maka Anda dapat memberikan preferensi dalam interval atas, menambah bobot pada definisi interval. Atau Anda dapat dengan mudah memilih 1, 2 atau 3 warna paling terang dalam gambar dan menambahkannya ke palet. Karena itu, jika Anda membutuhkan 16 warna, buat palet 13 warna dan tambahkan warna-warna cerah secara manual.


Palet dengan tiga warna paling cerah.

Sekarang semuanya terlihat cukup bagus, tetapi gambarnya terlalu jerawatan. Ini memiliki area besar dengan warna yang sama. Sekarang kita perlu memuluskannya.

Dithering


Saya tidak perlu memberi tahu Anda apa itu dithering, karena Anda sudah bekerja dengan pixel art. Jadi, untuk mendapatkan gambar yang lebih halus, kita akan menggunakan salah satu algoritma dithering, yang sangat banyak.

Saya menerapkan algoritma dithering sederhana Floyd-Steinberg . Tidak ada kejutan yang tidak menyenangkan. Namun, efeknya cukup kuat. Ini contoh kita lagi:


Asli

Lalu kami memotong palet menjadi 16 warna:


Nilai-nilai dipetakan ke palet 16-warna.

Dan sekarang dithering diikuti oleh konversi ke palet:


Hasil jadi dengan dithering

Source: https://habr.com/ru/post/id464203/


All Articles