C #으로 아일랜드 맵에 대한 마스크를 생성하는 쉽고 쉬운 방법을 찾고 있습니다.
기본적으로 지형이 물로 둘러싸여 있지 않은 펄린 노이즈로 생성 된 임의의 하이트 맵을 사용하고 있습니다.
다음 단계는 모서리와 경계가 물이되도록 마스크를 생성하는 것입니다.
그런 다음 펄린 노이즈 이미지에서 마스크를 빼서 섬을 얻을 수 있습니다.
명암을 가지고 놀면서
그래디언트 커브를 사용하면 원하는대로 아일랜드 하이트 맵을 얻을 수 있습니다.
(이것은 물론 예일뿐입니다)
보시다시피, 섬의 "가장자리"는 잘려 나옵니다. 색상 값이 너무 흰색이 아닌 경우 큰 문제는 아닙니다. 왜냐하면 회색조를 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;
}
}