Dunia 'belantara' yang dihasilkan secara prosedural sangat besar

76

Saya yakin Anda semua tahu tentang game seperti Dwarf Fortress - hutan belantara dan daratan yang sangat besar dan prosedural. Sesuatu seperti ini, diambil dari artikel yang sangat berguna ini.

Namun, saya bertanya-tanya bagaimana saya bisa menerapkan ini pada skala yang jauh lebih besar; skala Minecraft muncul dalam pikiran (bukankah itu kira-kira 8x ukuran permukaan bumi?). Pseudo-tak terbatas, saya pikir istilah terbaiknya.

: D

Artikel ini berbicara tentang kebisingan perlin fraktal. Saya bukan ahli dalam hal itu, tetapi saya mendapatkan ide umum (ini semacam suara yang dihasilkan secara acak yang semi-koheren, jadi bukan hanya nilai piksel acak).

Saya hanya bisa mendefinisikan daerah X dalam ukuran X, menambahkan beberapa jenis barang daerah pemuatan, dan memiliki sedikit kebisingan menghasilkan suatu daerah. Tapi ini hanya akan menghasilkan pulau dalam jumlah besar.

Pada ekstrem yang lain, saya tidak berpikir saya benar-benar dapat menghasilkan selembar perlin supermasif. Dan itu hanya akan menjadi satu pulau besar, saya pikir.

Saya cukup yakin Perlin noise, atau noise, akan menjadi jawaban dalam beberapa cara. Maksudku, petanya benar-benar bagus. Dan Anda bisa mengganti ascii dengan ubin, dan mendapatkan sesuatu yang terlihat sangat bagus.

Bebek Komunis
sumber
9
"akan menghasilkan pulau-pulau dalam jumlah besar" - Atau menghasilkan tanah dengan danau di dalamnya, jika Anda hanya bertukar tanah / air.
3
Meski begitu, Anda akan mendapatkan danau dalam jumlah besar, dalam pola yang cukup standar.
Bebek Komunis
3
@Kylotan: Mincraft berukuran tak terbatas (yah tidak juga, tapi benar-benar besar ... total volume = long.MaxValue x 128 x long.MaxValue). Oleh karena itu, ia tidak menghasilkan seluruh dunia dalam satu tembakan dan juga tidak menyimpan seluruh peta dalam memori. Ini menghasilkan wilayah blok 16x128x16 asynchronous jika mereka belum dikunjungi sebelum dinyatakan memuat mereka dari disk.
zfedoran
2
@The Communist Duck: Ya ini benar, permainan seperti minecraft dapat digunakan dengan menggunakan sekitar 2 hingga 4 byte data per blok tetapi hanya satu byte yang perlu disimpan setelah tidak lagi terlihat (satu byte menggambarkan jenis blok , byte lainnya menjelaskan pencahayaan dan data lain yang dapat dihitung ulang nanti). Di sinilah mulai menarik, Anda dapat menggunakan RLE untuk secara drastis mengurangi ukuran yang disimpan menjadi hanya beberapa byte karena blok agak koheren, seperti yang Anda sebutkan.
zfedoran
4
'Sungguh besar' tidak sama dengan tak terbatas dan Anda tidak dapat menggunakan kedua istilah secara bergantian. Jika Anda menumbuhkan peta sebagai dan ketika ditemukan, itu adalah ukuran terbatas yang tumbuh sesuai permintaan - proposisi yang sangat berbeda dari menjadi tak terbatas. Setiap bit pertumbuhan dapat dihasilkan sesuai kebutuhan. Data medan di Minecraft sangat cocok untuk kompresi sepele karena ada tingkat koherensi yang tinggi di antara data. (mis. RLE sebagaimana disebutkan.)
Kylotan

Jawaban:

35

Saya pikir saya lebih mengerti apa yang Anda minta sekarang.

Kebisingan tidak acak - tampak acak tetapi sepenuhnya didasarkan pada rumus matematika dan dapat diulang. Semua informasi dikodekan dalam formula. Ini berarti bahwa Anda dapat memiliki rumus yang berpotensi mencakup area tak terbatas, dan cukup gunakan rumus pada koordinat area yang Anda butuhkan. Saat Anda membutuhkan area yang berdekatan, Anda cukup menggunakan ulang rumus pada koordinat baru, dan karena rumus menghasilkan nilai kontinu, area tersebut akan bergabung dengan mulus.

Berikut adalah contoh yang disederhanakan, menggunakan sinus bukannya perlin noise untuk generasi tinggi, dan membayangkan dunia tak terbatas dalam sumbu X tetapi hanya 1 unit tinggi di sumbu Y dan Z.

Formula adalah: height(x,y) = sin(x/20)

Permainan dimulai, dan kami menghasilkan ketinggian untuk area terdekat, yaitu. (0,0) hingga (9,0):

[0.0, 0.05, 0.10, 0.15, 0.20, 0.25, 0.30, 0.34, 0.39, 0.43]

Kami memiliki bukit, naik ke arah kanan. Katakanlah kita berjalan sampai akhir dan perlu menghasilkan nilai dari (10,0 hingga 19,0) sekarang:

[0.48, 0.52, 0.56, 0.61, 0.64, 0.68, 0.72, 0.75, 0.78, 0.81]

Perhatikan bagaimana bukit terus naik dengan mantap, dan bahwa nilai pada (10,0) mengikuti dengan baik dari yang di (9,0). Ini karena fungsi sinus kontinu, yang pada dasarnya berarti bahwa jika Anda memasukkan 2 angka yang berdekatan, Anda akan mendapatkan 2 hasil yang berdekatan - untuk definisi tertentu yang berdekatan. Jadi jika Anda menggunakan koordinat dunia Anda sebagai parameter untuk fungsi yang mendefinisikan dunia Anda, Anda akan mendapatkan lanskap berkelanjutan yang cocok bersama tidak peduli berapa banyak atau sedikit dari itu Anda hasilkan sekaligus. Ketika Anda menghasilkan bagian baru, mereka akan mengalir dari bagian yang ada secara otomatis, karena ketinggian sudah ditentukan sebelumnya.

Jika dunia tidak akan berubah, Anda bahkan tidak perlu menyimpan apa pun, karena Anda dapat menghitung dengan tepat berapa tinggi pada titik tertentu dari rumus. Tentunya dengan sesuatu seperti Minecraft, dunia ini benar-benar dapat dideformasi sehingga Anda hanya menyimpan setiap potongan saat Anda membuatnya. Mengingat bahwa ada tingkat koherensi yang tinggi antara potongan yang berdekatan (mis. Jika 1 blok adalah rumput, kemungkinan besar blok di sebelahnya juga rumput). Anda dapat mengompres data dengan sangat efisien - pengkodean jangka panjang akan bekerja baik, tapi kemudian hampir semua algoritma kompresi standar.

Sedangkan saya telah berbicara tentang tinggi sebagai nilai yang paling jelas, Anda dapat menggunakan sistem yang sama untuk menghasilkan karakteristik apa pun yang Anda inginkan. Gunakan fungsi matematika dengan sifat kontinu dan di mana inputnya adalah koordinat dunia Anda dan yang dapat menentukan keberadaan landmark, deposit mineral, titik spawn, apa pun yang Anda suka. (Jelas nilai-nilai dalam satu formula dapat memengaruhi formula lainnya - tidak ada titik menempatkan deposit batubara di udara, sehingga Anda menghasilkan peta ketinggian dunia dan kemudian hanya menghitung kemungkinan batubara untuk blok yang cukup jauh di bawah tanah.)

Kylotan
sumber
Anda pasti membantu menjernihkan hal-hal, terima kasih. :) Tetapi sesuatu seperti fungsi noise tidak akan berlanjut. Dan AFAICS, jika terus menerus saya tidak akan menerima dunia 'acak'. Atau saya kehilangan sesuatu di sini?
Bebek Komunis
Maaf untuk komentar ganda, tetapi saya merasa di atas terpisah dari ini. Ketika Anda mengatakan 'gunakan koordinat dunia untuk kebisingan perlin', apakah ini efek yang sama seperti menghasilkan lembar kebisingan 'besar' tetapi di beberapa bagian? Saya merasa agak lambat dalam penggunaannya hari ini.
Bebek Komunis
Nah, bunyi derau Anda tentu bisa berkelanjutan, dan biasanya demikian, karena Anda memuluskannya. Untuk memperlancar batas, Anda mungkin perlu sedikit membaca melintasi perbatasan, tetapi prinsipnya tetap sama. Jika noise yang dimaksud membutuhkan data pseudo-acak, maka Anda menghasilkannya dari jumlah yang diketahui - yaitu. hash koordinat dunia Anda. Outputnya kemudian dapat diprediksi.
Kylotan
2
Adapun keacakan, masing-masing dunia dapat memiliki nilai benih sendiri yang digunakan dalam perhitungan. misalnya. sin (x + seed) bukannya sin (x), dalam contoh saya di atas. Setiap benih yang berbeda akan menghasilkan dunia yang berbeda. Dan mengenai lembar besar ... Saya tidak yakin apa relevansi yang dimilikinya. Tidak masalah berapa banyak atau seberapa sedikit yang Anda hasilkan atau ketika Anda melakukannya. Keadaan awal dunia ditentukan oleh rumus matematika, dan Anda hanya menggunakan rumus itu untuk menemukan keadaan itu sebagai dan ketika Anda membutuhkannya.
Kylotan
32

Tutorial yang saya tulis bertahun-tahun lalu mungkin memberi Anda sesuatu seperti yang Anda inginkan:

teks alternatif

Jika Anda melakukan modifikasi pulau pada langkah terakhir, ia cenderung mengarah ke daratan tunggal yang tidak mencapai tepi peta.

banyak sekali
sumber
7
Visualisasi yang luar biasa!
zfedoran
3
Saya ingat menggunakan tutorial ini ketika melakukan disertasi Master saya pada simulasi fenomena alam. Saya menggunakan contoh "bukit" untuk membuat kubah langit di dunia 3D saya. Pengantar konsep generasi medan yang luar biasa.
C.McAtackney
1
Gila, itu luar biasa! Saya tidak tahu ada yang benar-benar menggunakannya.
murah hati
1
YA TUHAN !!! Saya juga menggunakan ini dalam proyek sebelumnya ... cara paling sederhana untuk menghasilkan medan yang pernah saya temui !!!
Perang
15

Untuk membuat pulau besar, Anda tidak perlu membuatnya sekaligus. Saya akan membangun daerah secara serempak saat Anda mengunjungi mereka.

Alih-alih menggunakan topeng untuk membuat pulau seperti yang dijelaskan artikel ini, satu hal yang dapat Anda lakukan adalah bermain dengan panjang gelombang oktaf perlin kebisingan untuk mencapai tampilan yang Anda inginkan. Biasanya, oktaf pertama menggambarkan bentuk umum medan. Semua oktaf setelah itu cukup menambahkan detail butiran halus. Karena itu, mainkan dengan panjang gelombang oktaf pertama untuk mengontrol seberapa besar daratan Anda. Jika Anda ingin daratan berada di tengah, Anda bisa mengurangi peta ketinggian dengan jumlah yang meningkat saat Anda menjauh dari pusat dan kemudian menormalkan kebisingan. Misalnya bayangkan menggabungkan keduanya untuk membuat pulau Anda:

oktaf pertama detail

Artikel ini seharusnya membantu: http://freespace.virgin.net/hugo.elias/models/m_perlin.htm

Jika Anda ingin mempelajari tentang dunia 3d tanpa batas dan tentang berbagai trik yang dapat Anda gunakan untuk mengubah tampilan medan melalui bermain dengan input dan output derau, lihat artikel ini: http://http.developer.nvidia.com /GPUGems3/gpugems3_ch01.html

Mungkin sedikit sulit dibaca jika Anda tidak terbiasa dengan grafik pipa dan pemrograman shader.

zfedoran
sumber
Jenis efek yang ingin saya capai adalah sesuatu seperti top down 2d dari peta Minecraft (bukan game) ... jika saya hanya menggunakan lebih sedikit oktaf, bukankah saya masih perlu menghasilkan lembaran besar suara perlin? Atau bisakah saya menghasilkan sedikit saja?
Bebek Komunis
Saya pikir Anda mungkin masih sedikit bingung tentang cara kerja perlin noise. Anda dapat menghasilkan potongan 16x16 blok individu dengan mengirimkan fungsi offset koordinat x dan y untuk noise perlin. Perhatikan bagaimana fungsi PerlinNoise_2D (float x, float y) mengambil dalam koordinat x dan y. Dengan kata lain itu menghasilkan noise untuk beberapa posisi (x, y). Juga, menghasilkan lebih sedikit oktaf tidak sama dengan mengubah panjang gelombang oktaf. Kurang oktaf => Kurang detail butiran halus.
Gelombang yang
Juga, berikut ini adalah artikel dengan kode yang menunjukkan kepada Anda bagaimana menerapkan zoom / wavelenghts lebih lama: dreamincode.net/forums/topic/66480-perlin-noise
zfedoran
7

Perlin kebisingan dan teman-teman adalah titik awal yang baik tetapi Anda mungkin ingin mengambil langkah lebih jauh. Sebagian besar generator berbasis kebisingan populer akan memberi Anda hasil yang cukup menarik. Agar medan menjadi realistis, Anda ingin melihat algoritme yang meniru efek erosi. Salah satu simulator dunia permainan-ish paling canggih di luar sana - Dwarf Fortress - melakukan simulasi erosi sebagai salah satu langkah pembangunan dunia.

Salah satu solusi keren yang pernah saya lihat dijelaskan dalam artikel "Advanced Particle Deposition" di Game Programming Gems 7. Ada banyak yang lain tersedia di Internet sehingga ada banyak sumber daya untuk menarik (misalnya 1 atau 2 ) .

Dominik D
sumber