Saya mencari cara yang bagus dan mudah untuk membuat topeng untuk peta pulau dengan C #.
Pada dasarnya saya menggunakan dengan heightmap acak yang dihasilkan dengan suara perlin, di mana medannya TIDAK dikelilingi oleh air.
Langkah selanjutnya adalah membuat topeng, untuk memastikan sudut dan perbatasan hanya air.
Lalu saya bisa mengurangi topeng dari gambar perlin noise untuk mendapatkan pulau.
dan bermain-main dengan kontras ..
dan kurva gradien, saya bisa mendapatkan peta ketinggian pulau seperti yang saya inginkan ..
(ini hanya contoh saja)
jadi seperti yang Anda lihat, "tepian" pulau hanya terpotong, yang bukan masalah besar jika nilai warnanya tidak terlalu putih, karena saya hanya akan membagi skala abu-abu menjadi 4 lapisan (air, pasir, rumput dan batu).
Pertanyaan saya adalah, bagaimana saya bisa menghasilkan topeng yang terlihat bagus seperti pada gambar kedua?
MEMPERBARUI
Saya telah menemukan teknik ini, tampaknya menjadi titik awal yang baik bagi saya, tetapi saya tidak yakin seberapa tepat saya bisa menerapkannya untuk mendapatkan hasil yang diinginkan. http://mrl.nyu.edu/~perlin/experiments/puff/
PEMBARUAN 2
ini solusi terakhir saya.
Saya telah mengimplementasikan makeMask()
fungsi di dalam loop normalisasi saya seperti ini:
//normalisation
for( int i = 0; i < width; i++ ) {
for( int j = 0; j < height; j++ ) {
perlinNoise[ i ][ j ] /= totalAmplitude;
perlinNoise[ i ][ j ] = makeMask( width, height, i, j, perlinNoise[ i ][ j ] );
}
}
dan ini adalah fungsi terakhir:
public static float makeMask( int width, int height, int posX, int posY, float oldValue ) {
int minVal = ( ( ( height + width ) / 2 ) / 100 * 2 );
int maxVal = ( ( ( height + width ) / 2 ) / 100 * 10 );
if( getDistanceToEdge( posX, posY, width, height ) <= minVal ) {
return 0;
} else if( getDistanceToEdge( posX, posY, width, height ) >= maxVal ) {
return oldValue;
} else {
float factor = getFactor( getDistanceToEdge( posX, posY, width, height ), minVal, maxVal );
return oldValue * factor;
}
}
private static float getFactor( int val, int min, int max ) {
int full = max - min;
int part = val - min;
float factor = (float)part / (float)full;
return factor;
}
public static int getDistanceToEdge( int x, int y, int width, int height ) {
int[] distances = new int[]{ y, x, ( width - x ), ( height - y ) };
int min = distances[ 0 ];
foreach( var val in distances ) {
if( val < min ) {
min = val;
}
}
return min;
}
ini akan memberikan output seperti pada gambar # 3.
dengan sedikit perubahan dalam kode, Anda bisa mendapatkan output yang diinginkan seperti pada gambar # 2 ->
public static float makeMask( int width, int height, int posX, int posY, float oldValue ) {
int minVal = ( ( ( height + width ) / 2 ) / 100 * 2 );
int maxVal = ( ( ( height + width ) / 2 ) / 100 * 20 );
if( getDistanceToEdge( posX, posY, width, height ) <= minVal ) {
return 0;
} else if( getDistanceToEdge( posX, posY, width, height ) >= maxVal ) {
return 1;
} else {
float factor = getFactor( getDistanceToEdge( posX, posY, width, height ), minVal, maxVal );
return ( oldValue + oldValue ) * factor;
}
}