Saya mempermainkan Perlin Noise setelah bekerja dengan Diamond Square. Saya mengikuti implementasi oleh Hugo Elias yang pada dasarnya, membuat serangkaian fungsi dengan x, y sebagai input untuk membuang setiap nilai koordinat.
Kode PHP saya ada di sini :
Saya punya dua pertanyaan:
Bagaimana cara menggunakan algoritma untuk menghasilkan peta ketinggian dalam array? Saya tidak sepenuhnya memahaminya dan hanya porting ke PHP pseudocode, tetapi melakukan fungsi terakhir (map_perlined) setelah membaca di suatu tempat bahwa algoritma "ajaib" memberi Anda nilai-nilai yang ditransisikan untuk setiap x, titik y diberikan (tampaknya, tanpa harus membaca nya nilai yang berdekatan), saya hanya mendapatkan ini ketika menggunakan fungsi acakmt_rand(-100,100)/100;
Dan ini saat menggunakan kriptografi: 1.0-(($n*($n*$n*15731+789221)+1376312589)&0x7fffffff)/1073741824.0;
(yang, BTW, dapat diimplementasikan "apa adanya" di PHP?):
Jadi, simpulkan, tiga pertanyaan:
- Apakah kode saya benar?
- Fungsi acak dapat porting ke PHP seperti yang dijelaskan dalam kode? Tidak ada kesalahan, tapi hasilnya tidak ada.
- Bagaimana saya benar-benar menggunakan algoritma?
MEMPERBARUI
Ok, buat port PHP dari kode yang ditunjukkan di kertas Gustavson, dan seperti kata coder lainnya, itu hanya menghasilkan satu oktaf. Punya situs / kertas / panduan lain yang bermanfaat tentang cara menggunakan ini dengan konsep multi oktaf, amplitudo, frekuensi, dll. Untuk mengontrol fungsi noise? Pada makalah Gustavson hanya menunjukkan hasilnya, bukan implementasi sebenarnya dari algoritma, mungkin saya kehilangan sesuatu?
UPDATE 2
@NATHAN
Saya membuat sesuatu seperti:
$persistence = 0.5;
for ($j = 0; $j < $size; $j++) {
for ($i = 0; $i < $size; $i++) {
for ($o = 0; $o < 8; $o++) {
$frequency = pow(2,$o);
$amplitude = pow($persistence, $o);
$value += SimplexNoise($i*$frequency, $j * $frequency) * $amplitude;
}
//$value = SimplexNoise($i, $j) + 0.5 * SimplexNoise($i, $j) + 0.25 * SimplexNoise($i, $j);
$this->mapArray[$i][$j] = new Cell($value);
Dan setelah menormalkan nilai ke 0..1, saya mendapatkan peta ketinggian yang agak membosankan seperti:
Bagaimana cara saya seed seed? Mungkin yang perlu saya terapkan adalah versi 3d dengan nilai ketiga tinggi acak? Tetapi jika demikian, saya harus mencari tahu untuk mempertimbangkan nilai tetangga, yang akan saya akhiri dengan sesuatu seperti algoritma berlian persegi, persis apa yang tidak ingin saya lakukan.
PEMBARUAN 3
Lebih banyak pekerjaan Perlin. Saya belum menemukan cara untuk memandu suara ke hasil saya. Periksa oktaf ini dan hasil akhirnya:
Oktaf I ke IV
Jumlahkan
Setiap oktaf hampir sama. Periksa kode:
$persistence = 0.5;
for ($j = 0; $j < $size; $j++) {
for ($i = 0; $i < $size; $i++) {
$value = 0;
for ($o = 0; $o < 4; $o++) {
$frequency = pow(2,$o);
$amplitude = pow($persistence, $o);
$value += improved_noise($i*$frequency, $j*$frequency, 0.5)*$amplitude;
}
$this->map[$i][$j] = new Cell($value);
Hasilnya dinormalisasi. Apa yang akan Anda gunakan memiliki pengaruh kuat dalam pengembangan kebisingan? Saya melihat contoh di mana mengubah amplitudo memberikan permukaan lunak atau kasar, tetapi bahkan jika saya memberikan amplitudo besar, saya melihat sedikit perbedaan.
Jawaban:
Apa yang Anda implementasikan bukanlah Perlin noise. Saya tidak yakin mengapa Hugo Elias mengatakan itu, tapi dia bingung. Ini adalah implementasi referensi Ken Perlin. Itu tidak benar-benar memanggil generator nomor acak eksternal, tetapi menggunakan fungsi hash built-in untuk menghasilkan vektor gradien pseudorandom.
Perhatikan juga bahwa kebisingan Perlin hanya terdiri dari satu oktaf. Merangkum beberapa oktaf (contoh skala fungsi noise), seperti yang disarankan Hugo Elias, adalah teknik yang berguna, tetapi bukan bagian dari noise Perlin. Apa yang Anda dapatkan dengan melakukan itu disebut fraktal noise, kadang-kadang "fraktal Brownian noise" (karena kemiripan yang seharusnya dengan gerakan Brown).
Jika Anda ingin memahami secara geometris apa yang dilakukan algoritma, coba makalah ini . Ini tentang berbagai jenis suara yang disebut "simplex noise", tetapi juga termasuk penjelasan tentang kebisingan Perlin klasik. Kebetulan, noise simpleks juga ditemukan oleh Perlin dan seharusnya menjadi peningkatan dari noise klasiknya, jadi Anda dapat mencoba mengimplementasikannya juga jika Anda tertarik bermain dengan fungsi noise.
sumber
Itu kesalahpahaman umum. Apa yang disebut Hugo Elias kebisingan "Perlin" sebenarnya kebisingan fraktal, atau merah muda. Untuk lebih memahami apa itu kebisingan Perlin, Anda dapat membaca artikel Perlin yang ditautkan dalam jawaban Nathan Reed, atau libnoise docs (ada kesalahan yang sama di sana: Perlin noise adalah apa yang mereka sebut noise Gradient), atau CoherentNoise docs .
Sekarang, untuk benar-benar menjawab pertanyaan Anda: Anda tidak mendapatkan hasil yang diharapkan karena frekuensi noise terlalu tinggi. Frekuensi Anda mulai dengan 1 dan meningkat, artinya setiap piksel di peta yang dihasilkan memiliki nilai acak. Untuk melihat struktur peta yang lebih halus, Anda perlu "memperbesar" noise. Saya tidak benar-benar berbicara PHP, tapi saya kira kodenya akan terlihat seperti ini:
Artinya, Anda "meregangkan" satu periode kebisingan di seluruh peta Anda. Tentu saja, Anda dapat menggunakan koefisien lain - coba saja yang berbeda, lihat apa yang terjadi.
sumber