펄린 노이즈

[섬네일|에서의 3D [펄린 노이즈 2차원 슬라이스]]

**펄린 노이즈**(Perlin noise)는 켄 펄린이 1983년에 개발한 그래디언트 노이즈의 한 종류이다. 절차적으로 지형을 생성하고, 변수에 의사 난수적 변화를 적용하며, 이미지 텍스처 생성을 돕는 등 다양한 용도로 사용된다. 일반적으로 2차원, 3차원, 또는 4차원으로 구현되지만, 임의의 차원으로 정의할 수 있다.

## 역사

켄 펄린은 당시 컴퓨터 생성 이미지(CGI)의 "기계적인" 모습에 대한 불만으로 1983년에 펄린 노이즈를 개발했다. 그는 1985년 SIGGRAPH 논문 "이미지 신시사이저"에서 자신의 발견을 공식적으로 설명했다. 그는 디즈니의 컴퓨터 애니메이션 SF 영화 트론(1982) 작업을 매티컬 애플리케이션 그룹 (MAGI)에서 한 후 이를 개발했다. 1997년에 펄린은 이 알고리즘을 개발한 공로로 아카데미 과학기술상을 수상했으며, 그 내용은 다음과 같다:

펄린은 이 알고리즘에 대해 어떤 특허도 신청하지 않았지만, 2001년에는 심플렉스 노이즈의 3D 이상 구현을 텍스처 합성에 사용하는 것에 대한 특허를 받았다. 심플렉스 노이즈는 동일한 목적을 가지고 있지만, 더 간단한 공간 채우기 그리드를 사용한다. 심플렉스 노이즈는 펄린의 "클래식 노이즈"가 가지고 있던 계산 복잡성과 시각적으로 중요한 방향성 아티팩트와 같은 문제점들을 완화한다.

## 용도
섬네일|펄린 노이즈를 사용하여 생성된 가상 풍경
펄린 노이즈는 절차적 텍스처 원시 요소로, 시각 효과 아티스트가 컴퓨터 그래픽스에서 사실감을 높이기 위해 사용하는 그래디언트 노이즈의 한 종류이다. 이 함수는 의사 난수적 모양을 가지지만, 모든 시각적 세부 사항은 동일한 크기이다. 이 특성 덕분에 쉽게 제어할 수 있다. 펄린 노이즈의 여러 스케일된 사본을 수학적 표현식에 삽입하여 다양한 절차적 텍스처를 만들 수 있다. 펄린 노이즈를 사용한 합성 텍스처는 CGI에서 객체 표면, 불, 연기, 구름과 같은 컴퓨터 생성 시각 요소를 자연의 텍스처가 가진 제어된 무작위적 모양을 모방하여 더 자연스럽게 보이도록 만드는 데 자주 사용된다.

섬네일|펄린 노이즈로 생성된 가상 유기 표면
또한 데모와 같이 메모리가 극히 제한된 상황에서 텍스처를 생성하는 데 자주 사용된다. 프랙탈 노이즈 및 심플렉스 노이즈와 같은 후속 기술은 그래픽 처리 장치에서 실시간 컴퓨터 그래픽스와 모든 종류의 컴퓨터 그래픽스에서 비실시간 절차적 텍스처 생성에 거의 보편적으로 사용되고 있다.

이것은 비디오 게임에서 자연스러운 절차적으로 생성된 지형을 만드는 데 자주 사용된다. 이러한 성공은 펄린 노이즈의 계층적 구조가 자연적으로 발생하는 계층적 구조를 모방하며, 따라서 환경 과학 응용 분야에서도 유용하다는 것이 밝혀졌다.

## 알고리즘 상세
섬네일|프랙탈 노이즈를 만들기 위해 스케일이 조정되고 서로 추가된 펄린 노이즈. 각 단계에서 노이즈 주파수는 두 배가 되고 진폭은 절반이 된다.
섬네일|2차원 펄린 노이즈에 영점에서 등고선이 표시되어, 노이즈가 기울기 메시 교차점에서 0임을 보여준다.

펄린 노이즈는 주로 2차원, 3차원 또는 4차원 함수로 구현되지만, 임의의 차원 수에 대해 정의할 수 있다. 구현은 일반적으로 세 단계를 포함한다: 무작위 기울기 벡터의 그리드 정의, 기울기 벡터와 오프셋 사이의 스칼라곱 계산, 그리고 이 값들 사이의 보간.

### 그리드 정의
alt=|none|섬네일|256x256픽셀|기울기 벡터의 2차원 그리드
각 그리드 교차점에 고정된 무작위 -차원 단위 길이 기울기 벡터가 연결된 -차원 그리드를 정의한다. 단, 1차원인 경우에는 기울기가 −1과 1 사이의 무작위 스칼라이다.

### 스칼라곱
alt=|none|섬네일|256x256픽셀|각 점과 가장 가까운 그리드 노드 기울기 값의 스칼라곱. 셀의 다른 세 노드와의 스칼라곱은 표시되지 않았다.

임의의 후보 점의 값을 계산하기 위해 먼저 점이 놓여 있는 고유한 그리드 셀을 찾는다. 그런 다음 해당 셀의 개 모서리와 해당 모서리에 연결된 기울기 벡터를 식별한다. 다음으로, 각 모서리에 대해 오프셋 벡터를 계산한다. 오프셋 벡터는 해당 모서리에서 후보 점까지의 변위 벡터이다.

각 모서리에 대해 해당 기울기 벡터와 후보 점까지의 오프셋 벡터 사이의 스칼라곱을 계산한다. 후보 점이 그리드 모서리에 정확히 위치하면 이 스칼라곱은 0이 된다.

2차원 그리드의 점의 경우, 4개의 오프셋 벡터와 스칼라곱을 계산해야 하며, 3차원에서는 8개의 오프셋 벡터와 8개의 스칼라곱을 계산해야 한다. 일반적으로 이 알고리즘은 차원에서  복잡도를 가진다.

### 보간
alt=|none|섬네일|256x256픽셀|최종 보간 결과
마지막 단계는 개의 스칼라곱을 보간하는 것이다. 보간은 개 그리드 노드에서 1차 도함수 (그리고 아마도 2차 도함수)가 0인 함수를 사용하여 수행된다. 따라서 그리드 노드에 가까운 지점에서는 출력값이 노드의 기울기 벡터와 노드까지의 오프셋 벡터의 스칼라곱에 근사하게 된다. 이는 노이즈 함수가 모든 노드에서 0을 통과함을 의미하며, 이는 펄린 노이즈의 특징적인 모습을 부여한다.

일 경우, 그리드 노드 0의 값 과 그리드 노드 1의 값  사이를 보간하는 함수의 예는 다음과 같다.

:f(x) = a_0 + \operatorname{smoothstep}(x)\cdot(a_1-a_0) \quad \text{for }0\leq x\leq 1

여기서 스무스스텝 함수가 사용되었다.

컴퓨터 그래픽스에 사용되는 노이즈 함수는 일반적으로 범위 의 값을 생성하며 그에 따라 스케일링할 수 있다.

## 기울기 순열
켄 펄린의 원래 구현에서는 간단한 해싱 기법을 사용하여 각 그리드 교차점과 연결된 기울기 벡터를 결정했다. 미리 계산된 순열 테이블을 사용하여 주어진 그리드 좌표를 난수로 변환한다. 원래 구현은 256개 노드 그리드에서 작동했으며 다음 순열 테이블을 포함했다.


```c
int permutation[] = { 151, 160, 137,  91,  90,  15, 131,  13, 201,  95,  96,  53, 194, 233,   7, 225,
                      140,  36, 103,  30,  69, 142,   8,  99,  37, 240,  21,  10,  23, 190,   6, 148,
                      247, 120, 234,  75,   0,  26, 197,  62,  94, 252, 219, 203, 117,  35,  11,  32,
                       57, 177,  33,  88, 237, 149,  56,  87, 174,  20, 125, 136, 171, 168,  68, 175,
                       74, 165,  71, 134, 139,  48,  27, 166,  77, 146, 158, 231,  83, 111, 229, 122,
                       60, 211, 133, 230, 220, 105,  92,  41,  55,  46, 245,  40, 244, 102, 143,  54,
                       65,  25,  63, 161,   1, 216,  80,  73, 209,  76, 132, 187, 208,  89,  18, 169,
                      200, 196, 135, 130, 116, 188, 159,  86, 164, 100, 109, 198, 173, 186,   3,  64,
                       52, 217, 226, 250, 124, 123,   5, 202,  38, 147, 118, 126, 255,  82,  85, 212,
                      207, 206,  59, 227,  47,  16,  58,  17, 182, 189,  28,  42, 223, 183, 170, 213,
                      119, 248, 152,   2,  44, 154, 163,  70, 221, 153, 101, 155, 167,  43, 172,   9,
                      129,  22,  39, 253,  19,  98, 108, 110,  79, 113, 224, 232, 178, 185, 112, 104,
                      218, 246,  97, 228, 251,  34, 242, 193, 238, 210, 144,  12, 191, 179, 162, 241,
                       81,  51, 145, 235, 249,  14, 239, 107,  49, 192, 214,  31, 181, 199, 106, 157,
                      184,  84, 204, 176, 115, 121,  50,  45, 127,   4, 150, 254, 138, 236, 205,  93,
                      222, 114,  67,  29,  24,  72, 243, 141, 128, 195,  78,  66, 215,  61, 156, 180 };
```


이 특정 순열이 절대적으로 필요한 것은 아니지만, 0부터 255까지의 정수로 이루어진 무작위 배열이 필요하다. 새로운 순열 테이블을 생성할 때 값의 균일한 분포를 보장하도록 주의해야 한다.

순열 테이블을 사용하여 기울기 벡터를 얻으려면, 그리드 점의 좌표를 순열 테이블에서 순차적으로 찾아 이전 좌표의 순열에 각 좌표의 값을 더한다. 예를 들어, 원래 구현은 3D에서 다음과 같이 수행했다.


```c
// Values above 255 were handled by repeating the permutation table twice.
static final int p[] = new int[512];
static { for (int i=0; i < 256 ; i++) p[256+i] = p[i] = permutation[i]; }

int hash = p[p[p[X] + Y] + Z];
```


그런 다음 알고리즘은 해시 출력의 하위 4비트를 보고 해당 그리드 포인트에 대한 12개의 기울기 벡터 중 하나를 선택한다.

## 복잡도
노이즈 함수의 각 평가에 대해, 포함하는 그리드 셀의 각 노드에서 위치 및 기울기 벡터의 스칼라곱이 평가되어야 한다. 따라서 펄린 노이즈는 차원에 대해  복잡도로 스케일링된다. 복잡도 스케일링이 개선되면서 유사한 결과를 생성하는 펄린 노이즈의 대안으로는 심플렉스 노이즈와 오픈심플렉스 노이즈가 있다.

## 같이 보기
* 값 노이즈
* 시뮬레이션 노이즈
* 심플렉스 노이즈

## 각주

## 외부 링크

* 맷 주커의 펄린 노이즈 수학 FAQ
* 롭 파버의 CUDA 지원 그래픽 프로세서에서 펄린 노이즈 생성 및 시각화를 시연하는 튜토리얼
* 제이슨 베빈스의 복잡하고 일관된 노이즈 값을 생성하기 위한 광범위한 C++ 라이브러리
* PHP 구현 (GitHub)
* 펄린 노이즈 심층 설명 (C++ 소스 코드 포함)
* 파트리시오 곤살레스 비보 & 젠 로우의 셰이더 북
* 펄린 노이즈 온라인 생성기
* 펄린 노이즈 생성을 위한 파이썬 패키지
* SDL을 이용한 무작위 지형 생성 및 펄린 노이즈

분류:컴퓨터 그래픽스
분류:프랙탈
분류:특수 효과