Phong에서 PBR까지 (5) - GGX, Smith, Schlick은 무엇일까?

Cook-Torrance Microfacet BRDF를 구성하는 GGX, Geometry, Fresnel 항의 역할과 Roughness의 의미를 살펴봅니다.

Series Phong에서 PBR까지 5 / 6

이전 편

이전 글에서 Microfacet Specular BRDF는 크게 세 부분으로 나뉜다고 했다.

$$ f_s = \frac{DGF} {4(N\cdot L)(N\cdot V)} $$

각 항은 다음 역할을 담당한다.

D : Microfacet의 Normal 분포
G : Microfacet 간의 Masking / Shadowing
F : Fresnel Reflection

실시간 렌더링에서는 이 항들을 정확하게 계산하기보다는 충분히 현실적이면서 계산하기 좋은 모델을 선택한다.

이 과정에서 자주 등장하는 이름이

GGX + Smith + Schlick

이 조합을 조금 더 정확히 부르면 GGX NDF + Smith-GGX geometry/visibility + Schlick Fresnel이다. 세 이름은 서로 다른 항의 모델을 가리키며, GGX는 분포 함수 D뿐 아니라 Smith 항의 단일 방향 함수 $G_1$에도 쓰인다.

이다.


GGX — D

GGX는 Normal Distribution Function이다.

즉 다음 질문에 답한다.

현재 Half Vector 방향을 향하는 Microfacet이 얼마나 존재하는가?

대표적인 형태는 다음과 같다.

$$ D_{GGX}(N,H,\alpha) = \frac{\alpha^2} {\pi ((N\cdot H)^2(\alpha^2-1)+1)^2} $$

여기서 $\alpha$는 표면의 Roughness와 관련된 값이다.

렌더러에 따라 사용자가 입력한 Roughness를 그대로 쓰지 않고 제곱 등의 remapping을 거쳐 $\alpha$로 사용하는 경우가 많다.

GGX라는 이름은 이 절에서는 NDF $D$를 가리킨다. 다만 GGX의 microfacet 기하 가정은 뒤에서 볼 Smith 항에도 들어간다. Filament의 Standard Model은 GGX NDF와 Smith-GGX 가시성 항을 함께 사용한다.

중요한 것은 정확한 식보다 의미다.

낮은 Roughness

       ↑↑↑
       ↑↑↑
----------------

Microfacet Normal들이 한쪽으로 집중된다.

→ 좁고 강한 Highlight

높은 Roughness

    ↖ ↑ ↗ ↘ ↙
----------------

Microfacet Normal들이 넓게 분포한다.

→ 넓고 흐릿한 Highlight

Phong의 shininess가 하이라이트의 폭을 직접 조절했다면,

GGX에서는 표면의 미세한 Normal 분포를 변화시킨 결과로 하이라이트 폭이 변한다.


Smith — G

다음은 Geometry 항이다.

Microfacet들은 서로를 가릴 수 있다.

        /\
   /\  /  \   /\
__/  \/    \_/  \__

빛이 Microfacet에 도달하지 못하는 Shadowing,

반사된 빛이 카메라에 도달하지 못하는 Masking을 고려해야 한다.

이를 모델링하는 대표적인 방식이 Smith Geometry Function이다.

개념적으로는

$$ G(L,V,\alpha) = G_1(L,\alpha)G_1(V,\alpha) $$

처럼 입사 방향과 출사 방향 각각에서 얼마나 가려지는지를 계산한다.

각 방향에서 보이는 비율을 $G_1$로 나타낼 때, 독립적인 Smith 근사는 $G=G_1(L)G_1(V)$처럼 쓸 수 있다. 여기서 $G_1$에 GGX를 적용한 것이 Smith-GGX다. Filament의 Standard Model은 입사광과 시선의 가림 관계까지 함께 고려하는 height-correlated Smith-GGX visibility를 사용한다. 따라서 “GGX 기반”을 D만 뜻하는 좁은 의미로 쓰는 문맥과, D와 G의 GGX 구성을 함께 가리키는 넓은 의미의 문맥을 구분해야 한다.

즉,

Light에서 보이는가?
        ×
Camera에서 보이는가?

를 계산한다고 이해하면 된다.


Schlick — F

마지막 F는 Fresnel이다.

정확한 Fresnel equation을 매 pixel마다 계산하는 것은 실시간 렌더링 입장에서 부담스러울 수 있다.

그래서 널리 사용하는 근사가 Schlick Approximation이다.

$$ F=F_0+(F_{90}-F_0)(1-V\cdot H)^5 $$

여기서 $F_0$는 정면에서의 기본 반사율이고, $F_{90}$은 스침 각도에서의 반사율이다.

흔히 쓰는 $F_{90}=1$을 대입하면 $F=F_0+(1-F_0)(1-V\cdot H)^5$로 단순화된다. Filament의 Standard Model도 $F_{90}=1$인 Schlick 근사를 사용한다.

각도가 비스듬해질수록 Fresnel 항이 커지면서 반사가 강해진다.

정면

     Eye
      ↓
-------------
반사 비교적 약함


비스듬한 각도

Eye → → →
-------------
반사 강함

코드로 보면 의외로 단순하다

Microfacet BRDF를 구현한 코드는 대략 다음과 같은 모습이 된다.

vec3 H = normalize(L + V);

float D =
    DistributionGGX(N, H, roughness);

float G =
    GeometrySmith(N, V, L, roughness);

vec3 F =
    FresnelSchlick(dot(H, V), F0);

vec3 specular =
    (D * G * F)
    /
    (
        4.0
        * max(dot(N, V), 0.0)
        * max(dot(N, L), 0.0)
    );

Phong과 비교해보자.

Phong

vec3 R = reflect(-L, N);

float specular =
    pow(max(dot(R, V), 0.0), shininess);

Microfacet

D = Microfacet Distribution
G = Geometry
F = Fresnel

specular = D * G * F / ...

Phong에서는 하나의 경험적인 함수가 Highlight 전체를 결정했다.

Microfacet에서는 그 현상을 여러 물리적인 요소로 나눈다.


Roughness는 Shininess와 무엇이 다른가?

처음에는 다음처럼 대응해서 이해해도 좋다.

Phong                   PBR

Shininess 높음    ↔    Roughness 낮음
Shininess 낮음    ↔    Roughness 높음

하지만 둘은 같은 값이 아니다.

Shininess

하이라이트를 얼마나 좁게 만들 것인가?

라는 결과 중심의 값이다.

Roughness

Microfacet들의 Normal 방향이
얼마나 퍼져 있는가?

라는 표면 모델의 값이다.

따라서 의미 자체가 다르다.


그래서 “GGX 기반"이라는 말의 의미

이제 다음 문장을 해석할 수 있다.

GGX 기반 PBR을 사용한다.

정확히 풀어 말하면 보통

Microfacet BRDF에 GGX NDF를 사용하고, Smith-GGX Geometry/Visibility와 Schlick Fresnel을 조합한다.

는 의미에 가깝다.

그리고 흔히

GGX NDF            → D
Smith-GGX          → G 또는 visibility V
Schlick Fresnel    → F

와 같은 조합을 사용한다.

이것은 현대 실시간 렌더링에서 매우 익숙한 구조다.

이제 마지막 질문이 남는다.

그렇다면 PBR은 정확히 무엇일까?

GGX와 PBR은 같은 것일까?

그리고 Unreal Engine의

Base Color
Metallic
Roughness
Specular

는 지금까지 본 수식과 어떻게 연결될까?

마지막 글에서 이를 정리한다.



다음 편

참고 자료