Saya memiliki medan yang dihasilkan, dengan geometri heksagonal, seperti tangkapan layar di bawah:
Saya kemudian menghasilkan bioma, tetapi seperti yang Anda lihat, perbatasan di antara mereka benar-benar jelek dan lurus. Untuk menyembunyikan asal heksagonal itu, saya perlu memuluskan perbatasan antara bioma. Beginilah tampilannya sekarang dalam bingkai gambar dengan wajah tringular asli:
Yang saya tuju adalah sesuatu yang lebih seperti ini:
Setiap dhuwur memiliki attibute yang memegang tipe bioma, saya juga dapat menambahkan atribut khusus ke simpul di tepi antara dua bioma, tapi sepertinya saya tidak bisa menemukan cara melakukan ini dalam kode shader, jelas noise terlibat di sini, tetapi bagaimana cara membuatnya terus-menerus melintasi beberapa wajah dan seluruh perbatasan beberapa bioma?
Saya melakukan rendering dengan WebGL menggunakan THREE.js
Jawaban:
Jawaban lain di sini menyarankan menggunakan tekstur. Inilah teknik yang tidak menggunakan tekstur.
Anda ingin batas antara segi enam menjadi menarik. Lebih mudah untuk membuat batas-batas yang menarik ketika Anda memindahkannya ke tengah apa yang Anda gambar. Alih-alih menggambar ubin secara langsung, Anda menggambar "dual" ubin. Teknik ini disebut "ubin sudut" (di sini dan di sini dan di sini ). Ganda dari segi enam adalah segitiga, jadi kita akan menggambar segitiga ini bukannya segi enam:
Batas antara segi enam sekarang di tengah segitiga yang diberikan, sehingga akan memungkinkan kita melakukan lebih banyak hal menarik dengan mereka. Bonus: Anda hanya perlu menggambar dua segitiga per segi enam, bukan enam (atau dua puluh empat seperti yang Anda lakukan sekarang).
Di dalam masing-masing segitiga itu kita ingin shader fragmen untuk menggambar segi enam. Kita bisa melakukannya dengan koordinat barycentric . Letakkan (1,0,0), (0,1,0), dan (0,0,1) di setiap sudut segitiga. Di dalam segitiga, koordinat tersebut akan diinterpolasi. Shader fragmen akan menerima (a, b, c) dan dapat melihat untuk melihat nilai mana yang terbesar - yang akan memberi tahu kita yang mana dari tiga segi enam yang harus ditarik pada titik ini.
float max_n = max(barycentric.r, max(barycentric.g, barycentric.b)); if (max_n == barycentric.r) { color = v_color0; } else if (max_n == barycentric.g) { color = v_color1; } else if (max_n == barycentric.b) { color = v_color2; }
Itu untuk garis lurus.
Jika Anda ingin tepi yang bising, Anda dapat menambahkan noise ke koordinat barycentric:
Dengan bermain dengan panjang gelombang amplitudo / frekuensi noise, Anda bisa mendapatkan beberapa efek keren:
Anda harus berhati-hati dengan kebisingan, memastikan itu konsisten melintasi batas segitiga. Salah satu cara untuk melakukannya adalah dengan memasukkan hex id dan menggunakannya sebagai nilai seed untuk masing-masing dari tiga nilai noise yang ditambahkan ke koordinat barycentric.
Saya membuat demo interaktif di sini . (Untuk demo saya tidak menerapkan hex id atau beberapa hal lain yang mungkin Anda perlukan jika Anda membuat ini berfungsi dalam proyek nyata - itu hanya demo cepat & kotor)
sumber
Saya yakin bahwa "bisa" diselesaikan dengan beberapa algoritma gambar tetapi jika itu saya, saya mungkin akan menyelesaikannya dengan tekstur. Saya akan membuat tekstur heksagonal, menempatkan semuanya dalam atlas tekstur, kemudian untuk setiap segi enam, saya akan melihat tetangganya dan memutuskan tekstur mana yang akan diterapkan.
Tekstur perlu memiliki versi untuk setiap jenis medan plus versi untuk setiap jenis transisi.
Ini mirip dengan berapa banyak sistem berbasis ubin yang melakukan medan. Berikut ini contoh dari game 2d .
Kemungkinan lain adalah hanya memiliki tekstur untuk berbagai jenis medan (air, salju, kotoran, rumput) dan menambahkan jumlah campuran ke setiap titik segi enam untuk memutuskan bagaimana cara mencampurnya.
Artikel ini menunjukkan ide pencampuran tekstur medan. Saya tidak menyarankan mengikuti implementasi mereka tetapi itu menunjukkan ide.
sumber
Pertama, render bioma Anda menjadi tekstur. Petakan segitiga untuk texcoords. Anda dapat melakukan ini menggunakan proyeksi mercator, atau, lebih baik, peta kubus . Sekarang, di shader fragmen, lakukan sesuatu seperti ini:
di mana
noise
ada beberapa fungsi pseudo-acak (menggunakan, katakanlah, sinusoid) pada posisi 3D dari vertex dalam ruang model yang mengembalikan offset berisik ke koordinat tekstur. Cicipi tekstur yang digunakanGL_NEAREST
untuk menjaga batas yang tajam.sumber