[Noise] Fractal Brownian Motion - Perlin Noise
자연현상을 묘사하기 위해, 우리는 펄린노이즈라는 노이즈를 사용합니다. 그냥 랜덤함수만 사용하면 너무 규칙적이기 때문에 자연현상과 너무 다르기 때문이죠.
이번에는 들판의 잔디같은 것들을 컴퓨터 그래픽스에서 어떻게 움직일 수 있는지에 대해 이해해보겠습니다.
잔디는 파동 형태로 흔들리게 할 수도 있죠. 파동의 중요한 특성은 두가지가 있는데 진폭과 주파수입니다
float amplitude = 1.;
float frequency = 1.;
y = amplitude * sin(x * frequency);
좀 더 이것저것 합친 파형을 만들기 위해선 파동을 합칠 수 있습니다. 물리학 시간에 배웠을 수도 있는데요. 이를 superposition(중첩)이라고 합니다.
파동들을 더하면 다음과 같은 모양이 될 수도 있습니다.
float amplitude = 1.0;
float frequency = 1.0;
y = sin(x * frequency);
float t = 0.01 * (-u_time * 130.0);
y += sin(x * frequency * 2.1 + t) * 4.5;
y += sin(x * frequency * 1.72 + t * 1.121) * 4.0;
y += sin(x * frequency * 2.221 + t * 0.437) * 5.0;
y += sin(x * frequency * 3.1122 + t * 4.269) * 2.5;
y *= amplitude * 0.06;
그런데 여기서 문제는 어쨌든 파동을 합치더라도 규칙적인 파형이 반복된다는 것입니다. 규칙을 없애는 것처럼 보이게 하기 위해서는 파동을 매우 많이 겹쳐야할텐데 비효율적이죠. 그래서 등장한 것이 노이즈 함수입니다.
여러 번의 **노이즈(iterations)**를 추가함으로써, 주파수를 점진적으로 증가시키고 진폭을 감소시켜 노이즈의 세밀한 부분을 만들어낼 수 있습니다. 이 기술을 프랙탈 브라운 운동(Fractal Brownian Motion, fBM) 또는 간단히 프랙탈 노이즈라고 부릅니다.
이 방식을 응용한것이 펄린 노이즈입니다. 그래서 펄린노이즈 함수를 사용할 때 보통 이름을 PerlinFbm()으로 사용하기도 하죠. 펄린노이즈는 완전 랜덤이 아니고 어느정도 균일한 모양을 가진 랜덤 값입니다. 따라서 어떠한 값x를 넣으면 고정된 f(x)값이 나오죠.
일반 value noise는 완전한 랜덤으로 2차원으로 뽑아내면 다음과 같습니다.
예전에 TV에서 채널이 안나오면 이상한 주파수가 나온 적이 있을텐데 바로 이러한 원리입니다.
Perlin Noise는 다음과 같이 나옵니다.
재밌는 것은 이것도 파동 처럼 주파수와 옥타브를 변경하여 다양하게 노이즈를 생성할 수 있다는 것입니다.
원리 코드는 다음과 같습니다. 사인파를 합친것과 비교해보면 어느정도 이해가 갈 것입니다.
// Properties
const int octaves = 1;
float lacunarity = 2.0;
float gain = 0.5;
//
// Initial values
float amplitude = 0.5;
float frequency = 1.;
//
// Loop of octaves
for (int i = 0; i < octaves; i++) {
y += amplitude * noise(frequency*x);
frequency *= lacunarity;
amplitude *= gain;
}
펄린노이즈는 1차원, 2차원, 3차원으로 이용할 수 있는데 3차원은 구름같은 공간 렌더링시 필요하고, 잔디의 흔들림은 x,z축을 이용하므로 2차원이면 됩니다.
펄린 노이즈의 코드는 오픈소스로 나와있으나 한번에 이해하기 힘들다면 다양한 쉐이더토이 예제의 코드를 보며 비교해가며 실험해보면 이해에 도움이 될 것입니다.
참고자료 :
파형 및 노이즈 원리 설명 :
https://thebookofshaders.com/13/?lan=kr
The Book of Shaders
Gentle step-by-step guide through the abstract and complex universe of Fragment Shaders.
thebookofshaders.com
PerlinNoise 오픈소스 :
https://github.com/Reputeless/PerlinNoise
GitHub - Reputeless/PerlinNoise: Header-only Perlin noise library for modern C++ (C++17/C++20)
Header-only Perlin noise library for modern C++ (C++17/C++20) - Reputeless/PerlinNoise
github.com
펄린 및 구름 노이즈 쉐이더 토이 예제 :
https://www.shadertoy.com/view/3dVXDc
Shadertoy
0.00 00.0 fps 0 x 0
www.shadertoy.com