2014년 9월 10일

모바일에서의 물리 기반 셰이딩

저자: Brian Karis

이 글은 아마도 심층분석 시리즈의 첫번째로, UE4 의 고도로 기술적인 기능에 대해 논합니다.

이 글은 UE4 에 사용된 셰이딩 모델을 설명했던 언리얼 엔진 4 의 리얼 셰이딩에서 했던 얘기에 이어지는 부분입니다. 이 글은 일련의 부분에 익숙한 독자를 대상으로 합니다.

그 프리젠테이션 이후로 몇 가지 자잘한 변화가 있었습니다. 지오메트리 텀에 Disnet 의 'hotness' 변경 부분을 제거했습니다. Eric Heitz 의 최근 논문으로 셰이딩과 마스킹 사이의 상관관계를 추가하기 위해 이 부분을 다시 개선시킬 수도 있겠습니다. Cavity 파라미터는 전혀 들어가지 못했습니다. 프리젠테이션 직전에 변경을 하려 했으나, 제어가능한 유전체 스페큘러 반사율에 쓰이는 것을 발견했습니다. 그 대신 Disney 모델에 정의된 대로 Specular 파라미터를 사용합니다.

이 셰이딩 모델에서 제가 정말로 이야기하고 싶었던 것은, 이 셰이딩 모델을 모바일 플랫폼에 어떻게 적응시켰는가 입니다. UE4 의 모바일 렌더러에 대해 제대로 참고할 수 있는 자료는 GDC 의 이 슬라이드를 참고하세요. 어떻게 사용되었는지에 대한 예제는 아이패드 에어에서 4xMSAA 1080p @ 30hz 로 실행되는 Zen 테크 데모 또는 소울 테크 데모를 확인하시기 바랍니다.

처음서부터 한 가지 주요한 목표는, 고사양 PC 와 제작 작업방식이 동일했으면 했다는 점입니다. 모바일 디바이스에서 실행할 때도 모든 것이 고사양 렌더러에서 보는 것과 거의 같을 수 있도록 같은 애셋을 렌더링하는 기능도 지원했으면 했습니다. 감마를 바로 구해오는 자잘한 것들 여러가지를 뜻하지만, 머티리얼이 PC, 콘솔, 모바일 디바이스에서 전부 같은 방식으로 작동하는 것처럼 보이도록 셰이딩 역시도 같은 방식으로 작동해야 한다는 뜻이기도 합니다.그러기 위해 앞의 이야기에서 설명했던 것과 같은 머티리얼 모델을 지원합니다. BaseColor, Metallic, Specular, Roughness, 이 파라미터들은 똑같은 방식으로 작동합니다.

물론 모바일 디바이스의 연산력은 훨씬 떨어지기 때문에 모든 라이트에 BRDF 를 계산할 수는 없습니다. 사실 동적으로 계산되는 디렉셔널 선 라이트는 하나만 지원합니다. 그림자는 미리 계산되어 텍스처 스페이스에 부호화된 디스턴스 필드로 저장됩니다. 다른 모든 라이트는 라이트맵에 구워집니다. 라이트맵은 고사양에서처럼 유사 HDR 인코딩된 SH 디렉셔널 표현을 사용하지만 별도의, 비상관, 알파 압축이 없는 PVRTC 로 더 잘 압축되도록 적응시켰습니다. 고사양에서처럼 미리계산된 스페큘러는 미리꼬인(preconvolved) 인바이언먼트 맵을 사용합니다. 똑같은 미리꼬기가 사용되었으며, 라이트맵으로 인해 비슷하게 정규화 및 스케일이 적용됩니다. 모바일의 경우 픽셀당 단 하나의 인바이언먼트 맵만 가져(fetch)옵니다.

인바이언먼트 BRDF

흥미로운 부분은, 고사양용 '인바이언먼트 BRDF' 계산 방식이 Monte Carlo 통합으로 미리 계산되어 2D LUT 에 저장된다는 점입니다. 의존적 텍스처 펫치는 일부 모바일 하드웨어에서 정말 비싼데, 더 심한 것은 OpenGL ES2 의 8 샘플러 제한이 극도로 제한된다는 점입니다. 이 LUT 로 샘플러를 씹어먹는 것은 도저히 용납할 수가 없었습니다. 그 대신 Dimitar Lazarov 의 작업을 기반으로 한 추정 분석 버전을 만들었습니다. 형태는 유사하되 우리 셰이딩 모델과 러프니스 파라미터에 꼭 맞도록 적응된 것입니다. 그 함수는 아래와 같습니다:

half3 EnvBRDFApprox( half3 SpecularColor, half Roughness, half NoV )

{

const half4 c0 = { -1, -0.0275, -0.572, 0.022 };

const half4 c1 = { 1, 0.0425, 1.04, -0.04 };

half4 r = Roughness * c0 + c1;

half a004 = min( r.x * r.x, exp2( -9.28 * NoV ) ) * r.x + r.y;

half2 AB = half2( -1.04, 1.04 ) * a004 + r.zw;

return SpecularColor * AB.x + AB.y;

}

즉 이미지 기반 라이팅에 그럴싸한 프레넬과 러프니스 효과가 생긴다는 뜻입니다.

EnvBRDF used on high end

고사양에 사용된 EnvBRDF

 

EnvBRDFApprox Used On Mobile

모바일에 사용된 EnvBRDFApprox

 

메탈릭과 스페큘러 머티리얼 출력이 언제 연결이 안되는지 (즉 디폴트가 사용되는지) 감지합니다. 이 부분은 전형적인 비금속에는 사실입니다. 이 경우 함수를 더욱 최적화시킬 수 있습니다.

half EnvBRDFApproxNonmetal( half Roughness, half NoV )

{

// Same as EnvBRDFApprox( 0.04, Roughness, NoV )

const half2 c0 = { -1, -0.0275 };

const half2 c1 = { 1, 0.0425 };

half2 r = Roughness * c0 + c1;

return min( r.x * r.x, exp2( -9.28 * NoV ) ) * r.x + r.y;

}

인바이언먼트 맵도 함께 피하기위해 비슷한 최적화가 이루어졌습니다. 일부 게임에서는 노 스페큘러에 대해 최적화를 하지만, 에너지가 보존되지 않습니다. 그 대신 우리에게는 Roughness=1 로 설정하고 상수 인자를 빼내 최적화시키는 'Fully rough' 플래그가 있습니다. 여기서 알 수 있는 것은:

EnvBRDFApprox( SpecularColor, 1, 1 ) == SpecularColor * 0.4524 - 0.0024

여기서 이렇게 단순화시켰습니다:

DiffuseColor += SpecularColor * 0.45;

SpecularColor = 0;

퍼포먼스가 정말 많이 아쉬운 엄선된 오브젝트에만 이 플래그를 사용합니다.

디렉셔널 라이트

마지막으로 손대고자 했던 부분은 태양광 계산 방식입니다. 태양은 동적으로 계산되는 유일한 라이트라고 앞서 말씀드린 바 있습니다. 불행히도 단 하나의 라이트일 뿐인데도 최대 고사양 셰이딩 모델은 여전히 너무 무겁습니다. EnvBRDF 로 추정치를 미리 통합시킨 형태로 그 일부분만 계산했습니다. 또한 인바이언먼트 맵을 샘플링하는 데 사용되었던 리플렉션 벡터도 이미 있습니다. 인바이언먼트 맵을 프리파일러(prefiler)하는 데 사용되는 방사향 대칭 로브를 분석적으로 계산한 다음 IBL 에 했던 것처럼 EnvBRDF 로 결과를 곱하는 것입니다. 이 부분은 인바이언먼트 맵으로 했던 계수적 통합이 아닌, 로브를 입사광 반대 방향으로 로브를 분석적으로 통합시키는 것으로 생각해 볼 수 있습니다.

먼저 GGX NDF 를 Blinn 으로 대체합니다. 그런 다음 방사형 대칭 퐁 로브로 Blinn 을 추정해 냅니다.

$$ \newcommand{\nv}{\mathbf{n}} \newcommand{\lv}{\mathbf{l}} \newcommand{\vv}{\mathbf{v}} \newcommand{\hv}{\mathbf{h}} \newcommand{\mv}{\mathbf{m}} \newcommand{\rv}{\mathbf{r}} \newcommand{\ndotl}{\nv\cdot\lv} \newcommand{\ndotv}{\nv\cdot\vv} \newcommand{\ndoth}{\nv\cdot\hv} \newcommand{\ndotm}{\nv\cdot\mv} \newcommand{\vdoth}{\vv\cdot\hv} D_{Blinn}(\hv) = \frac{1}{ \pi \alpha^2 } (\ndoth)^{ \left( \frac{2}{ \alpha^2 } - 2 \right) } \approx \frac{1}{ \pi \alpha^2 } (\rv\cdot\lv)^{ \left( \frac{1}{ 2 \alpha^2 } - \frac{1}{2} \right) } $$

$\rv$ 은 리플렉션 방향입니다. $\rv = 2(\ndotv)\nv - \vv$

퐁은 스페리컬 가우시안으로 더더욱 추정해 냅니다:

$$ x^n \approx e^{ (n + 0.775) (x - 1) } $$

그러면 최종 최적화 형태가 뜹니다.

half D_Approx( half Roughness, half RoL )

{

half a = Roughness * Roughness;

half a2 = a * a;

float rcp_a2 = rcp(a2);

// 0.5 / ln(2), 0.275 / ln(2)

half c = 0.72134752 * rcp_a2 + 0.39674113;

return rcp_a2 * exp2( c * RoL - c );

}

$\frac{1}{\pi}$ 는 라이트 색에 영향을 끼칩니다.

결과적으로 매우 저렴하면서도 합리적인 셰이딩 모델이 생겼습니다. 스페큘러는 에너지를 보존하며, 전파 지표각에서도 합리적인 결과가 나고, 분석적 광원으로도 이미지 기반 광원으로도 정상 작동합니다. 심지어 모바일 하드웨어는 더이상 모바일 기반이 아니라는 것은 변명입니다.

에픽 게임스에서는 여러분께 별도의 귀속 문구 없이 이 기사의 코드 샘플을 마음대로 사용, 복사, 변경, 배포할 수 있는 권한을 드렸습니다.