我正在寻找一种使用C#为岛地图生成蒙版的好方法。
基本上,我使用的是由Perlin噪声生成的随机高度图,其中地形没有被水包围。
下一步将是生成遮罩,以确保拐角和边界都是水。
然后,我可以从Perlin噪声图像中减去蒙版以获得一个孤岛。
并在对比中玩。
和渐变曲线,就可以得到一个孤岛高度图。
(这些只是示例)
如您所见,岛上的“边缘”刚刚被切除,如果颜色值不是太白,这并不是一个大问题,因为我将灰度分为4层(水,沙子,草皮和岩)。
我的问题是,如何像第二幅图像那样生成一个好看的蒙版?
更新
我已经找到了这项技术,这对我来说似乎是一个不错的起点,但是我不确定我可以如何正确地实现它以获取所需的输出。 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;
}
}