ฉันกำลังค้นหาวิธีที่ดีและง่ายในการสร้างมาสก์สำหรับแผนที่เกาะด้วย C #
โดยทั่วไปฉันใช้กับแผนที่ความสูงแบบสุ่มที่สร้างด้วยเสียงเพอร์ลินซึ่งภูมิประเทศไม่ได้ล้อมรอบด้วยน้ำ
ขั้นตอนต่อไปคือการสร้างหน้ากากเพื่อให้แน่ใจว่ามุมและเส้นขอบเป็นเพียงน้ำ
จากนั้นฉันก็สามารถลบหน้ากากออกจากภาพเสียงเพอร์ลินเพื่อเกาะได้
และเล่นกับความคมชัด ..
และเส้นโค้งการไล่ระดับสีฉันสามารถรับความสูงของเกาะได้เช่นเดียวกับที่ฉันต้องการ ..
(นี่เป็นเพียงตัวอย่างของหลักสูตร)
อย่างที่คุณเห็น "ขอบ" ของเกาะเพิ่งถูกตัดออกซึ่งไม่ใช่ปัญหาใหญ่ถ้าค่าสีไม่ขาวเกินไปเพราะฉันจะแบ่งสีเทาออกเป็น 4 ชั้น (น้ำทรายหญ้าและ ร็อค)
คำถามของฉันคือฉันจะสร้างมาสก์หน้าตาดีได้อย่างไรในภาพที่สอง?
UPDATE
ฉันได้พบเทคนิคนี้ดูเหมือนว่าจะเป็นจุดเริ่มต้นที่ดีสำหรับฉัน แต่ฉันไม่แน่ใจว่าฉันจะสามารถนำไปใช้เพื่อให้ได้ผลลัพธ์ที่ต้องการได้อย่างยอดเยี่ยมเพียงใด http://mrl.nyu.edu/~perlin/experiments/puff/
อัพเดท 2
นี่คือทางออกสุดท้ายของฉัน
ฉันใช้งานmakeMask()
ฟังก์ชั่นภายในลูปการทำให้ปกติของฉันเป็นแบบนี้:
//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 ] );
}
}
และนี่คือฟังก์ชันสุดท้าย:
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;
}
นี้จะให้ผลลัพธ์เช่นในภาพ # 3
ด้วยการเปลี่ยนแปลงเล็กน้อยในโค้ดคุณสามารถรับเอาต์พุตที่ต้องการเช่นในรูปภาพ # 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;
}
}