펄린 노이즈 함수를 이용한 파동
위에 노이즈 함수의 합 == 펄린 노이즈 함수
Large, Medium, Small의 변화가 섞여 있어 우리가 원하는 다양한 결과를 보여준다.
이 기법을 2D로 적용시켜보자.
2D로 만든 각각의 노이즈들을 합치면 자연스러운 값을 얻을 수 있다.
지속성(Persistence)
다양한 결과를 위해 진폭과 진동수의 적절한 수정이 필요.
지속성이란 값을 도입하여 간략화 해보자.
이 값은 프랙탈로 유명한 멘델브로트란 사람이 만들었다고 한다.
frequency = 2i
amplitude = persistencei
빈도수는 2의 승수로 올라가고 진폭을 지속성의 승수를 적용하여 처리한다.
Frequency | 1 | | 2 | | 4 | | 8 | | 16 | | 32 | |
|
Persistence = 1/4 | | + | | + | | + | | + | | + | | = | | |
Amplitude: | 1 | | 1/4 | | 1/16 | | 1/64 | | 1/256 | | 1/1024 | | result | |
|
Persistence = 1/2 | | + | | + | | + | | + | | + | | = | | |
Amplitude: | 1 | | 1/2 | | 1/4 | | 1/8 | | 1/16 | | 1/32 | | result | |
|
Persistence = 1 / root2 | | + | | + | | + | | + | | + | | = | | |
Amplitude: | 1 | | 1/1.414 | | 1/2 | | 1/2.828 | | 1/4 | | 1/5.656 | | result | |
|
Persistence = 1 | | + | | + | | + | | + | | + | | = | | |
Amplitude: | 1 | | 1 | | 1 | | 1 | | 1 | | 1 | | result | |
옥타브(Octaves)
노이즈 함수들이 더해지는 정도
어느정도를 더할지는 자유지만 지속성이 1보다 크면 모르겠지만 대부분 1보다 작으면 금방 작아지므로 매우 작은 결과값들이 더해질 것이기 때문에 적정선을 찾으면 좋겠다.
노이즈 함수 만들기
function Cubic_Interpolate(v0, v1, v2, v3,x)
P = (v3 - v2) - (v0 - v1)
Q = (v0 - v1) - P
R = v2 - v0
S = v1
return Px3 + Qx2 + Rx + S
end of function
|
| |
부드러운 노이즈
보간으로도 어느정도 부드럽게 얻어낼 수 있지만 한계가 있다.
이미지 필터링과 같은 방식으로 이웃 값들을 얻어와 평균을 내는 방식을 사용해 더 부드러운 값을 얻어낸다.
1차원 처리
function Noise(x)
.
.
end function
function SmoothNoise_1D(x)
return Noise(x)/2 + Noise(x-1)/4 + Noise(x+1)/4
end function
2차원 처리
function Noise(x, y)
.
.
end function
function SmoothNoise_2D(x>, y)
corners = ( Noise(x-1, y-1)+Noise(x+1, y-1)+Noise(x-1, y+1)+Noise(x+1, y+1) ) / 16
sides = ( Noise(x-1, y) +Noise(x+1, y) +Noise(x, y-1) +Noise(x, y+1) ) / 8
center = Noise(x, y) / 4
return corners + sides + center
end function
최종 결과물
지금까지 구현한 것을 모두 합쳐보자.
1차원 펄린 노이즈
function Noise1(integer x)
x = (x<<13) ^ x;
return ( 1.0 - ( (x * (x * x * 15731 + 789221) + 1376312589) & 7fffffff) / 1073741824.0);
end function
function SmoothedNoise_1(float x)
return Noise(x)/2 + Noise(x-1)/4 + Noise(x+1)/4
end function
function InterpolatedNoise_1(float x)
integer_X = int(x)
fractional_X = x - integer_X
v1 = SmoothedNoise1(integer_X)
v2 = SmoothedNoise1(integer_X + 1)
return Interpolate(v1 , v2 , fractional_X)
end function
function PerlinNoise_1D(float x)
total = 0
p = persistence
n = Number_Of_Octaves - 1
loop i from 0 to n
frequency = 2i
amplitude = pi
total = total + InterpolatedNoisei(x * frequency) * amplitude
end of i loop
return total
end function
2차원 펄린 노이즈
function Noise1(integer x, integer y)
n = x + y * 57
n = (n<<13) ^ n;
return ( 1.0 - ( (n * (n * n * 15731 + 789221) + 1376312589) & 7fffffff) / 1073741824.0);
end function
function SmoothNoise_1(float x, float y)
corners = ( Noise(x-1, y-1)+Noise(x+1, y-1)+Noise(x-1, y+1)+Noise(x+1, y+1) ) / 16
sides = ( Noise(x-1, y) +Noise(x+1, y) +Noise(x, y-1) +Noise(x, y+1) ) / 8
center = Noise(x, y) / 4
return corners + sides + center
end function
function InterpolatedNoise_1(float x, float y)
integer_X = int(x)
fractional_X = x - integer_X
integer_Y = int(y)
fractional_Y = y - integer_Y
v1 = SmoothedNoise1(integer_X, integer_Y)
v2 = SmoothedNoise1(integer_X + 1, integer_Y)
v3 = SmoothedNoise1(integer_X, integer_Y + 1)
v4 = SmoothedNoise1(integer_X + 1, integer_Y + 1)
i1 = Interpolate(v1 , v2 , fractional_X)
i2 = Interpolate(v3 , v4 , fractional_X)
return Interpolate(i1 , i2 , fractional_Y)
end function
function PerlinNoise_2D(float x, float y)
total = 0
p = persistence
n = Number_Of_Octaves - 1
loop i from 0 to n
frequency = 2i
amplitude = pi
total = total + InterpolatedNoisei(x * frequency, y * frequency) * amplitude
end of i loop
return total
end function
원본 글을 참고하여 간단하게 펄린 노이즈에 대해서 정리해 보았다.
다양한 곳에 많이 사용되는 것이니까 개념을 잘 읽혀놓고
노이즈를 만드는 함수나 툴킷 클래스를 만들어 놓으면 유용하게 사용할 수 있을 것이다.