GPG 에 기술된 펄린노이즈
http://www.gpgstudy.com/gpgiki/PerlinNoise
원문
http://freespace.virgin.net/hugo.elias/models/m_perlin.htm
http://www.redwiki.net/wiki/wiki.php/Perlin%20Noise
* 원문링크 : http://freespace.virgin.net/hugo.elias/models/m_perlin.htm
- 원문 번역링크 : PerlinNoise
- 이 글은 제가 번역한 것이 아님을 밝힙니다. GpGiki에서 여러 전문가분들이 번역을 해주신 건데, 원문과 번역이 섞여있어 읽기 힘든 까닭에 제가 다시
정리하기 위해 이리로 복사해 온 것입니다. 원문을 읽어보시려면 위의 원문번역링크를 참조하시길...
1 시작하며
많은 사람들이 프로그램에서 불예측성을 만들어내고 물체의 동작과 행동이 좀더 자연스럽게 보이게 하거나 또는 텍스쳐를 생성해 내기 위해
난수생성기를 사용해 왔다. 난수생성기는 확실히 나름대로의 쓸모가 있지만, 종종 출력값들이 너무 조악해서 자연스러워 보이지 않을때가 있다.
이글에서는 매우 다양한 용도로 사용할 수 있는 함수 하나를 소개하겠다. 기본적으로 이 함수는 자연스럽게 보이는 뭔가가 필요한 경우라면 언제라도
사용할 수 있다. 이 글에서 필자가 제시하는 용도 이외의 용도들도 얼마든지 찾을 수 있을 것이다.
자연에 있는 많은 것들을 보게 되면, 그것들이 프랙탈이라는 것을 알게 될 것이다. 그것들은 다양한 수준의 정밀함(detail)을 가지고
있다. 산맥의 외곽선을 보게되면, 높이의 변화가 큰 것(산), 중간인 것(언덕), 작은 것(구릉), 조그마한 것(돌맹이), 그외에도 계속 나열할
수 있는 변화들이 있다. 더불어 들판에 누덕누덕 자라난 풀들의 분포, 바다의 파도, 개미의 이동, 나무가지의 뻗침, 구슬의 무늬, 바람같은
대부분의 삼라만상의 현상을 보면, 모두 크고 작은 차이지만 똑같은 경향을 보여준다. 펄린 노이즈 함수는 노이즈 함수를 다양한 비율의 범위로
더함으로써 간단히 이런 현상을 재창조한다.
펄린 노이즈 함수를 만들기 위해서는 노이즈 함수와 보간함수 두가지가 필요하다.
2 노이즈 함수의 소개
노이즈 함수는 본질적으로 seed 값에 의한 난수생성기이다. 인자로 하나의 정수를 받아서 그 인자에 기반한 난수를 반환한다. 만약
똑같은 인자를 두 번 전달하면 동일한 수가 두 번 생성된다. 이런 식으로 동작한다는 건 매우 중요한 사실이다. 그렇지 않다면 펄린 함수는
쓸모없는 것을 생성할 것이다.
여기 노이즈 함수의 예를 나타내는 그래프가 있다. 0 에서 1 사이의 난수가 X 축의 모든 점에 배정되었다.
이 값들 사이를 부드럽게 보간함으로써 전달인자를 정수로 받지 않는 연속적인 함수를 정의할수 있게 된다. 이 글의 뒤에서 이 값들을
보간하는 다양한 방법에 대해 논해보겠다.
3 정의
더 얘기하기 전에 진폭(amplitude)과 주파수(frequency)에 대해 내가 의도하려는 걸 정의해 보겠다. 만약 당신이 물리를
공부해왔다면 사인파에 적용된 진폭과 주파수의 개념이 떠오르는게 당연하다.
- sin 곡선 : sin 곡선의
파장은 한 꼭대기로부터 다른 꼭대기까지의 거리다. 진폭은 sin곡선의 높이다. 주파수는 1/wavelength 로 정의된다.
- 노이즈 곡선 : 이 노이즈 함수의
예제 그래프에서 빨간 점은 함수의 차원에 따라 정의된 난수값을 가리킨다. 이 경우에 진폭은 함수가 가질 수 있는 최대, 최소값의 차이가 된다.
파장은 한 빨간 점으로부터 다음 점까지의 거리이다. 역시 주파수는 1/wavelength 로 정의된다.
4 펄린 노이즈 함수 만들기
이제, 다양한 주파수와 진폭을 가진 부드러운 함수들을 많이 가지고 있다면, 그 함수들을 모두 더함으로써 멋진 노이즈 함수를 만들 수
있다. 이것이 펄린 노이즈 함수다.
다음 노이즈 함수들을
http://freespace.virgin.net/hugo.elias/models/noise_a.gif http://freespace.virgin.net/hugo.elias/models/noise_b.gifhttp://freespace.virgin.net/hugo.elias/models/noise_c.gif http://freespace.virgin.net/hugo.elias/models/noise_d.gifhttp://freespace.virgin.net/hugo.elias/models/noise_e.gif http://freespace.virgin.net/hugo.elias/models/noise_f.gif
모두 더해보자. 이런 것이 얻어진다.
이 함수가 큰, 중간정도의, 그리고 작은 변화들을 가지고 있다는 걸 볼수 있다. 당신은 이게 산맥하고 상당히 비슷하게 보인다고
생각할지도 모른다. 실제로 많은 컴퓨터가 생성한 지형은 이 방법으로 만들어진 것이다. 물론 그것들은 2차원 노이즈를 사용하고, 여기에 대해서는
잠시 후에 다루기로 하겠다.
물론 당신은 2차원에서도 똑같이 할수 있다. 몇몇 노이즈 함수는 2차원에서 생성된다.
http://freespace.virgin.net/hugo.elias/models/perlin_a.jpg http://freespace.virgin.net/hugo.elias/models/perlin_b.jpghttp://freespace.virgin.net/hugo.elias/models/perlin_c.jpg http://freespace.virgin.net/hugo.elias/models/perlin_d.jpghttp://freespace.virgin.net/hugo.elias/models/perlin_e.jpg http://freespace.virgin.net/hugo.elias/models/perlin_f.jpg
이 함수를 모두 더하면 하나의 노이즈 형태가 생성된다.
5 Persistence (지속성)
이 노이즈 함수들을 모두 더할때 각각의 함수가 정확히 어떤 진폭과 주파수를 사용하는지 궁금할 것이다. 위의 일차원 예제는 각각
연속적으로 더해지는 노이즈 함수에 대해 주파수는 두배로, 진폭은 반으로 해서 사용했다. 이것은 매우 잘 알려진 방법이다. 사실 사람들이 다른 걸
사용하려고 생각해 보지도 않을 정도로 너무 잘 알려져있다. 그러나 각 단계마다 다른 주파수와 진폭을 사용함으로써 다양한 특징의 펄린 노이즈
함수를 만들어낼 수 있다. 예를 들어 부드럽게 기복하는 언덕을 만들기 위해 큰 진폭과 낮은 주파수를 사용하거나 매우 작은 진폭에 높은 주파수를
사용할 수 있다. 또는 작은 진폭에 낮은 주파수를 선택해서 평평하지만 바위투성이인 평원을 만들 수도 있다.
좀 더 간단하면서 진폭과 주파수라는 말이 항상 반복되는걸 피하기 위해 하나의 숫자가 각 주파수의 진폭을 지정하는데 쓰인다. 이 값은
Persistence 로 알려져 있다. 이것의 정확한 의미에는 약간 모호성이 있다. 그 용어는 원래 프랙탈의 발견뒤에 있는 사람중 한명인
Mandelbrot 에 의해서 만들어졌다. 그는 높은 주파수를 많이 가지고 있는 노이즈를 persistence 가 낮다고 정의했다. 내 친구인
Matt 또한 persistence 의 개념을 보충했지만 다른 방법으로 정의했다. Mandelbrot 씨께 미안하지만, 솔직히 나는 Matt 의
정의를 선호한다. 그래서 우리의 persistence 의 정의는 다음과 같다.
frequency = 2^i amplitude = persistence^i
i 는 추가되는 i 번째 노이즈 함수를 가리킨다. 펄린노이즈의 출력에 persistence 의 효과를 설명하기 위해 아래의 도표를 한번
보자. 이것들은 더해지는 노이즈 함수의 구성요소, persistence 값의 효과, 펄린 노이즈 함수의 결과를 보여준다.
Frequency 1 2 4 8 16 32
Persistence = 1/4 http://freespace.virgin.net/hugo.elias/models/prln_b1.gif +http://freespace.virgin.net/hugo.elias/models/prln_b2.gif + http://freespace.virgin.net/hugo.elias/models/prln_b3.gif +http://freespace.virgin.net/hugo.elias/models/prln_b4.gif + http://freespace.virgin.net/hugo.elias/models/prln_b5.gif +http://freespace.virgin.net/hugo.elias/models/prln_b5.gif = http://freespace.virgin.net/hugo.elias/models/prln_br.gif
Amplitude: 1 1/4 1/16 1/64 1/256 1/1024 result
Persistence = 1/2 http://freespace.virgin.net/hugo.elias/models/prln_c1.gif +http://freespace.virgin.net/hugo.elias/models/prln_c2.gif + http://freespace.virgin.net/hugo.elias/models/prln_c3.gif +http://freespace.virgin.net/hugo.elias/models/prln_c4.gif + http://freespace.virgin.net/hugo.elias/models/prln_c5.gif +http://freespace.virgin.net/hugo.elias/models/prln_c6.gif = http://freespace.virgin.net/hugo.elias/models/prln_cr.gif
Amplitude: 1 1/2 1/4 1/8 1/16 1/32 result
Persistence = 1 / root2 http://freespace.virgin.net/hugo.elias/models/prln_a1.gif +http://freespace.virgin.net/hugo.elias/models/prln_a2.gif + http://freespace.virgin.net/hugo.elias/models/prln_a3.gif +http://freespace.virgin.net/hugo.elias/models/prln_a4.gif + http://freespace.virgin.net/hugo.elias/models/prln_a5.gif +http://freespace.virgin.net/hugo.elias/models/prln_a6.gif = http://freespace.virgin.net/hugo.elias/models/prln_ar.gif
Amplitude: 1 1/1.414 1/2 1/2.828 1/4 1/5.656 result
Persistence = 1 http://freespace.virgin.net/hugo.elias/models/prln_d1.gif +http://freespace.virgin.net/hugo.elias/models/prln_d2.gif + http://freespace.virgin.net/hugo.elias/models/prln_d3.gif +http://freespace.virgin.net/hugo.elias/models/prln_d4.gif + http://freespace.virgin.net/hugo.elias/models/prln_d5.gif +http://freespace.virgin.net/hugo.elias/models/prln_d6.gif = http://freespace.virgin.net/hugo.elias/models/prln_dr.gif
Amplitude: 1 1 1 1 1 1 result
6 옥타브
각각의 더해지는 연속적인 노이즈 함수를 옥타브라고 부른다. 이렇게 불리는 이유는 각각의 노이즈 함수가 이전의 것보다 두배의 주파수를
갖기 때문이다. 음악에서의 옥타브도 이런 성질을 갖는다.
정확히 얼마나 많은 옥타브를 더할것인가는 전적으로 당신에게 달렸다. 가능한한 많이 더할수도 있고 원하는 만큼 약간만 더할수도 있다.
그러나 약간의 제안을 하겠다. 만약 당신이 펄린 노이즈 함수를 화면에 이미지를 만드는데 사용중이라면 옥타브가 너무 높은 주파수를 가져서 화면에
표시할수 없을때가 올것이다. 매우 높은 주파수의 노이즈 함수의 작은 디테일을 모두 복사하기에는 화면의 픽셀이 충분하게 있지 않을 것이다. 펄린
노이즈의 몇몇 구현은 화면(또는 다른 매체)의 한계에 도달할때까지 가능한 만큼의 노이즈 함수를 자동적으로 더한다.
진폭이 너무 작아서 복사하지 못하게 될때 노이즈 함수를 더하는걸 중지하는게 현명하다. 정확히 언제 이런일이 일어나는지는
persistence 의 정도, 펄린 함수의 전체적인 진폭 그리고 화면(또는 뭐든지)의 해상도에 달렸다.
7 당신만의 노이즈 함수 만들기
우리는 노이즈 함수로 무엇을 할것인가? 기본적으로는 난수생성기로 사용한다. 하지만 다른 난수발생기에서 프로그램에서 호출할 때마다 매번
다른 난수를 만들어 내는 것과는 다르게, 노이즈 함수에서는 하나 또는 그 이상의 매개변수를 계산하여 난수를 발생시킨다. 예를 들어 똑같은 수를
노이즈 함수에 넘기면 함수는 매번 똑같은 수를 만들어 낼 것이지만, 다른 수를 넘겨주면 함수는 다른 수를 만들어 낼 것이다.
글쎄, 나는 난수생성기에 대해 많은걸 알지 못해서 뭔가 찾으러 다녔고, 여기 내가 발견한게 하나 있다. 이건 매우 좋아보인다. -1.0
과 1.0 사이의 부동소수를 돌려준다.
function IntNoise(32-bit integer: x) x = (x<<13) ^ x; return ( 1.0 - ( (x * (x * x * 15731 + 789221) + 1376312589) & 7fffffff) / 1073741824.0); end IntNoise function
이제 당신은 몇가지 난수생성기가 필요할 것이므로, 나는 위의 코드의 몇가지 복사본을 만들기로 제안한다. 하지만 약간만 다른 숫자를
사용한다. 저기 엄청나게 무서워 보이는 숫자들은 모두 소수들이다. 따라서 당신은 비슷한 크기의 몇개의 다른 소수를 사용할 수 있다. 당신이
난수를 찾는걸 돕기 위해 나는 소수를 나열하는 작은 프로그램을 만들었다. 시작할 숫자와 끝날 숫자를 넘겨주면 이 프로그램은 그 사이에 있는 모든
소수를 찾는다. 소스코드도 포함되어 있으니 무작위 소수를 생성하기 위해 당신은 자신의 프로그램에 쉽게 포함시킬수 있다. Primes.zip
8 보간
노이즈 함수를 만들면서 당신은 리턴값이 부드럽게 나오는것이 필요할 것이다. 또한번 당신이 좋아하는 어떤 방법이고 취할수 있지만, 어떤
방법은 다른 방법보다 더 나아 보인다. 표준보간함수는 이 값들 사이를 보간할 a, b 값과 0 과 1 사이의 값을 받을 x 값, 이렇게 3개의
입력을 받는다. 보간함수는 x 에 기반하여 a 와 b 사이의 값을 돌려준다. x 가 0이면은 a 를 돌려주고 x 가 1이면은 b 를 돌려준다.
x 가 0과 1사이면 a 와 b사이의 어떤 값을 돌려준다.
8.1 선형 보간
이처럼 간단한 '플라즈마'같은 형편없어 보이는 방법을 모든 이들이 지형생성을 위해 사용한다.(Looks awful, like those
cheap 'plasmas' that everyone uses to generate landscapes.) 비록 간단한 알고리즘이지만 펄린
노이즈를 실시간으로 사용할 거라면 용납될것 같다.
function Linear_Interpolate(a, b, x) return a*(1-x) + b*x end of function
8.2 코사인 보간
이 방법은 선형 보간보다 훨씬 부드러운 커브를 제공한다. 만약 속도 상의 약간의 손실을 감수할 수 있다면, 이 방법이 명백히 더 낫고
노력할만한 가치가 있다.
function Cosine_Interpolate(a, b, x) ft = x * 3.1415927 f = (1 - cos(ft)) * .5 return a*(1-f) + b*f end of function
8.3 3차 보간
이 방법은 매우 부드러운 결과를 제공하지만, 속도의 저하를 감수해야 한다. 솔직히 말하자면, 나는 이 방법이 코사인 보간보다 현저하게
더 나은 결과를 제공한다고는 확신할 수 없지만, 어쨋든 원한다면 사용하라. 다소 복잡하기 때문에 주의깊게 살펴보아야 한다. 이전의 보간함수가
세개의 입력을 취하는데 비해 3차 보간은 다섯개를 취한다. 이전것이 단지 a 와 b 만을 사용하는 대신에, 이제는 x 와 함께 v0, v1,
v2 와 v3 가 필요하다. 이것이 3차보간이다:
http://freespace.virgin.net/hugo.elias/models/m_inter4b.gif
v0 = the point before a v1 = the point a v2 = the point b v3 = the point after b
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
9 매끈한 노이즈
보간과는 다른 이야기지만, 노이즈 함수의 출력이 덜 랜덤하게 보이고 2D 나 3D 버전에서는 좀 덜 각지게(less square) 하기
위해 출력값을 부드럽게 조정할 수도 있다. smoothing 작업은 당신이 예측한 것과 많이 유사하고 이미지 smoothing 필터나 Fire
알고리즘을 만들어 본 적이 있는 사람이면 누구나 이미 이 작업에 정통하다. (Smoothing is done much as you would
expect, and anyone who has written an image smoothing filter, or fire algorithm
should already be familiar with the process.)
단순히 한 좌표에서의 노이즈 함수값을 얻는것보다는 그 값과 이웃값과의 평균을 얻을수도 있다. 이것이 이해가 잘 안된다면, 아래의
가상(psudo)코드를 한번 보라.
smooth 된 노이즈와 똑같은 노이즈 함수에 smoothing 되지 않은 것과의 차이를 설명한 작은 그림을 오른쪽에서 볼수 있다.
smooth 노이즈가 좀더 평평하며, 절대 smooth 처리되지 않은 노이즈의 극값에 도달하지 못하고, 주파수는 대충 반정도를 보인다는걸 알수
있다. 이게 유일한 효과이기 때문에 1차원 노이즈는 거의 smoothing할 만한 점이 없다. smoothing 은 노이즈의 각짐을 줄이는
효과를 볼 수 있는 2차원이나 3차원에서 더 유용하게 된다. 불행히도 약간 대비를 감소시키기도 한다. 더 smooth 하게 만들수록, 명백히,
노이즈는 더 평평해 질 것이다.
http://freespace.virgin.net/hugo.elias/models/smooth_n.gif http://freespace.virgin.net/hugo.elias/models/smooth_y.gif
1차원 Smooth 노이즈
function Noise(x) . . end function function SmoothNoise_1D(x) return Noise(x)/2 + Noise(x-1)/4 + Noise(x+1)/4 end function
2 차원 Smooth 노이즈
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
10 모두 합치기
이제 당신은 모두 다 알았다. 당신이 배워온것을 모두 합쳐서 펄린 노이즈 함수를 만들 시간이다. 단지 여러개의 보간된 노이즈 함수를
하나로 더하는 것임을 기억하라. 결국 펄린 노이즈는 단지 하나의 함수인 것이다. 하나이상의 전달인자를 넘기고 함수는 하나의 숫자로 응답한다.
여기 간단한 1차원 펄린 함수가 있다.
펄린 함수의 주된 부분은 루프다. 루프가 반복될 때마다 주파수가 두배가 되는 옥타브를 더한다. 되풀이될때마다 Noisei 로 표기되는
다른 노이즈 함수를 부른다. 이제 휴도코드가 보여주는 것처럼 각각의 옥타브마다 하나씩의 수많은 노이즈 함수를 실제로 쓸 필요는 없다. 3개의 큰
소수 값을 뺀 모든 노이즈 함수는 근본적으로 같기 때문에 똑같은 코드를 유지하던지 아니면 단순히 다른 소수세트를 사용할 수도
있다.
10.1 1차원 펄린 노이즈 Pseudo 코드
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차원 이상의 펄린노이즈 함수에 적용하는것은 쉽다.
10.2 2차원 펄린 노이즈 Pseudo 코드
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
11 펄린 노이즈의 응용분야
이제 이 멋진 함수를 갖게 됐으니, 이걸로 무엇을 해볼수 있을까? 흠, 상투적으로 생각해보더라도 당신의 상상력만이 이것의 활용분야를
제한한다. 펄린 노이즈는 내가 다 생각해 볼수도 없을 정도로 많은 응용분야를 가지고 있다. 어디 한번
보자.
11.1 1 차원
- 가상의 무엇을 제어하기 :
살아있는 것들은 매우 오랫동안 가만히 있는일이 드물다.(학생은 빼고) 게임의 예에서 가상 인간 플레이어가 좀더 생동감있게 보이도록 펄린 노이즈를
사용해 그의 관절위치를 부단히 보정해라.
- 스케치한 선을 그리기 : 컴퓨터가
그린 선은 항상 완벽하게 직선이어서 선이 부자연스럽고 친근감이 들지 않게 만들수 있다. 선이 손으로 그려진것마냥 보이게 만들기 위해 펄린노이즈
사용하여 선그리기 알고리즘에 흔들림을 삽입할수 있다. 구불구불한 원이나 상자를 그리는 것도 가능하다. 스케치 유저 인터페이스를 만들기 위한 몇몇
연구가 행해져 오고 있다.
11.2 2 차원
- 지형 : 2D 펄린 노이즈의
완벽한 응용분야중 하나다. 재분할(subdivision) 방법과는 다르게 메모리 어디에도 지형을 저장할 필요없이 그 지형의 어느지점의 높이든
쉽게 계산해낼수 있다. 게다가 지면은 (거의)무한히 늘려지고 미세한 디테일도 계산될 수 있어 다양한 정도의 디테일 생성에 완벽한 모습을
보여준다. 지형의 특성도 역시 쉽게 정의될 수 있다.
- 구름 : 또한, 구름생성도 펄린
노이즈에 잘 부합된다.
- 텍스쳐 생성 : 모든 종류의
텍스쳐가 펄린노이즈를 사용해서 생성될 수 있다. 몇가지 예제로 아래의 테이블을 보라. 생성된 텍스쳐는 (반복된다 해도)반복되기 전에 오랫동안
사용될수 있어서 반복적인 타일 텍스쳐 맵보다 훨씬 더 맘에 들게 만든다.
11.3 3 차원
- 3D 구름 : 물론 볼륨있는 구름을 만들수도 있다. 이걸 표시하려면은 아마도 몇가지 레이트레이싱을 사용해야만 할 것이다.
- 움직이는 구름 : 하나의 차원을 시간으로 간주하면, 3D 펄린 노이즈로 움직이는 2차원 구름을 만들수 있다.
- 속이 비지 않은 텍스쳐 : POVray 같은 몇몇 렌더링 / 레이트레이싱 프로그램은 3차원 텍스쳐로부터 충실하게 깍아낸
텍스쳐를 물체에 적용한다. 이것은 보통 (평평하지 않은) 3D 물체에 2D 텍스쳐를 매핑해 일어나는 일그러짐으로부터 텍스쳐가 상하는 일이
없다는걸 말한다.
11.4 4 차원
- 움직이는 3D 텍스쳐와 구름 :
고차원으로 올라가면 쉽게 움직이는 구름이나 솔리드 텍스쳐를 생성할수 있다. 단지 여분의 차원을 시간으로 간주하면 된다.
Copyright Matt Fairclough 1998. 이 그림에 있는 지형, 구름, 물은 모두 수학적으로 펄린노이즈
생성되었고 Terragen으로 만들어졌다.
이 데모에서 구름은 3D 펄린 노이즈로 움직여진다. 실시간으로 펄린 노이즈를 생성해 내기 위해 알고리즘이 약간 수정되어야만 했다.
어떻게 했는지 더 자세한 정보를 원한다면 Clouds Article을 보라.
12 Perlin Noise 를 이용한 텍스쳐 생성
Perlin을 이용한 텍스쳐 생성은 정말 환상적이다. 여러분은 메모리는 거의 차지하지 않으면서 무한히 큰(모든 실용적 목적으로)
텍스쳐를 생성할수 있다. 여러분은 대리석,나무,소용돌이 무늬등 여러분이 노력한다면 아마도 어떤 것이든 생성할 수 있다. 여러분은 또한 3차원
텍스쳐를 정의할수 있다. 여러분은 이것을 깍아서 어떤 물체를 만들수 있는 재질의 단단한 덩어리로 간주해도 된다. 이는 뒤틀림 없이 어떠한 모양의
물체에도 적용될수 있는 텍스쳐를 생성하게 해준다. 정말 괜찮은 텍스쳐를 얻기위해서는 많은 상상력과 생각, 경험을 필요로하지만 그 결과는 매우
인상적일 것이다.
당신 좋을대로 이리 저리 가지고 놀아보라. 텍스쳐를 만들기 위해 여러 펄린 함수를 사용하라, 여러가지 차원에서 다른 지속성과 주파수로
시도해보라. 여러분은 또다른것의 속성에 영향을 주기위해 하나의 Perlin 함수를 이용할수있다. 함수들을 결과에 적용하자. 여러분이 원하는데로
하라, 그것이 여러분이 꿈꾸는 어떤 텍스쳐를 생성하는 거의 확실한 방법이다.
다음의 텍스쳐는 삼차원 Perlin Noise 로 만들어졌다.
http://freespace.virgin.net/hugo.elias/models/perlsph2.gif http://freespace.virgin.net/hugo.elias/models/perlsph1.gif
표준 삼차원 Perlin Noise. 4 옥타브, 지속성 0.25 와 0.5
낮은 지속성. 여러분은 결과에 함수를 적용해 Perlin Noise에 날카로운 경계를 생성할수 있다.
더 흥미있고 복잡한 텍스쳐를 생성하기위해 여러분은 여러가지 Perlin 함수들을 섞어 시도해 봐야만한다. 이 텍스쳐는 두 부분으로
생성되었다. 첫번째로 낮은 지속성을 가진 Perlin 함수는 얼룩의 형태를 만드는데 이용되었다. 이 함수의 값은 두가지 다른 함수를 선택하는데
이용되었는데, 하나는 줄무늬를 위해, 다른 하나는 얼룩을 위한 함수이다. 앞부분은 높은 지속성의 함수가 많이 선택되었고, 뒷부분은 낮은 지속성의
함수가 많이 선택되었다. 줄무늬는 어떤 수와( 대략 20 ) 첫번째 Perlin 함수를 곱해서 생성되었고 그 다음 코사인을
취했다.
대리석무늬의 텍스쳐는 Perlin 함수를 코사인 함수에 대한 옵셋(상쇄?)으로 이용해 만들어 질수 있다.
texture = cosine( x + perlin(x,y,z) )
http://freespace.virgin.net/hugo.elias/models/perlsph9.gif http://freespace.virgin.net/hugo.elias/models/perlsph10.gif
아주 보기좋은 나무결 텍스쳐들도 만들수 있다. 결은 다음과 같은 낮은 persistence 를 가진 함수에 의해
만들어진다.
g = perlin(x,y,z) * 20 grain = g - int(g)
나무에서 볼수 있는 멋진 범프는 일차원에서 늘려져온 높은 주파수의 잡음이다.
bumps = perlin(x*50, y*50, z*20) if bumps < .5 then bumps = 0 else bumps = 1t
13 참고문헌 및 링크
- Procedural textures : http://developer.intel.com/drg/mmx/appnotes/proctex.htm 인텔 개발자 사이트의 실시간으로 펄린노이즈를 생성하는데 있어 새로운 MMX 기술사용법에 대한 기사
- Ken Perlin's Homepage : http://mrl.nyu.edu/perlin/ 나는 이 사람이 펄린노이즈에 응답하는게 당연하다고 생각한다. 그는 텍스쳐와 모델링에 대한 수많은 유용한 링크를 가진 흥미로운 페이지를 운영한다.
- Texturing And Modeling A Procedural Approach: http://www.cs.umbc.edu/~ebert/book/book.html 텍스쳐를 생성하기 위한 또다른 알고리즘과 다양한 자연현상 모델 얘기를 포함한 펄린 노이즈를 사용하는데 대한 깊은 정보가 있는 펄린의 책
- Procedural Texture Page: http://www.threedgraphics.com/pixelloom/tex_synth.html 이 페이지는 순차적 텍스쳐 합성(Procedural Texture Synthesis)에 관계된 모든 정보와 WWW 링크를 모으려는 시도를 하고 있다.
반응형
'알고리즘 & 자료구조 > 3D알고리즘&자료구조' 카테고리의 다른 글
펄린노이즈 2탄 (Perlin noise) (0) | 2012.10.27 |
---|---|
Hypercube Vertices (0) | 2012.10.27 |
플랙탈 - Apophysis, ultra fractal 5 (0) | 2012.10.27 |
프렉탈의 프로그래밍 (0) | 2012.10.27 |
클럭 : 게임의 심장박동 (0) | 2012.10.27 |