Skip to main content

다중산란에 관한 오해

8월

12, 2020

by c0de517e


테크

물리 기반 렌더링용 첨단 다중산란 GGX BRDF(양방향 반사율 분포함수)를 직접 구현해 봅시다.

물론 앞서 수학과 물리학 지식을 활용해 정교한 솔루션들을 만드는 전문가들이 이 함수를 이미 구현한 적이 있습니다. 이와 유사한 결과를 얻기 위한 자료 조사가 필요할 경우 다음 아티클들을 읽어 보세요.

하지만 지금은 이러한 조사는 생략하고 좀 더 쉬운 방법을 알아봅시다. 준비되셨나요?

우선 상관관계에 놓인 모든 스미스 픽싱(fixing)들을 가지고 전형적인 GGX 함수부터 시작해 봅시다. 아래의 이미지 시퀀스는 디즈니의 BRDF 익스플로러 환경 라이팅 모드로 생성된 것입니다. 이 시퀀스는 알파 = 거칠기 제곱을 매개변수화하여 0.3에서 0.9까지 거칠기가 변화하는 금속성 GGX를 나타냅니다.

이 재질은 높은 거칠기에서 지나치게 어둡게 나타납니다. 주지하듯 이미 똑똑한 전문가들이 이 문제를 열심히 연구해서 해결했습니다.

이제 위의 이미지를 Kulla/Conty의 다중산란 GGX BRDF와 비교해 봅시다.

수정 완료!

이제 이 솔루션이 효과적인 이유를 살펴봅시다. 수학적 원리는 이미 알려져 있지만, 다른 관련 문제들을 파악하는 시도 역시 흥미롭고 유용할 것입니다. 하지만 그러한 다른 문제는 생략하고 넘어가겠습니다.

처음으로 돌아가 봅시다. 현재 물리 기반 렌더링(PBR)이 선호되는 이유가 무엇일까요? 그저 물리학이 좋아서는 아닐 것입니다 (적어도 저는 좋아하지 않습니다). 물리 기반 렌더링이 물리학과 깊은 연관성이 있다고 해도, 물리학을 좋아하지 않는 것은 방대한 이미지 제작 과정에서 우리가 저지르는 보다 중대한 잘못들에 비하면 아주 작은 잘못에 불과합니다.

컴퓨터 그래픽은 예측성 렌더링이 아닙니다. 리얼리즘을 위해 물리적 지식을 시뮬레이션하는 것이 아닙니다. 목표는 그것이 아니라 아름다운 이미지를 만드는 것입니다.

아름다운 이미지를 만들기 위해 물리적 지식을 시뮬레이션하면 작업 흐름들을 간소화할 수 있음을 알 수 있었습니다. 여기에는 라이팅에서 재질 분리, 핵과 매개 변수의 수 줄이기, 실제 재질의 라이브러리 이용하기 등이 있습니다.

따라서 작업 방법에 대한 의사 결정을 내릴 때는 기술적 측면에 앞서 예술적인 관심 사항을 고려해야 합니다. 우리가 파악할 수 있는 예술적인 문제가 있다면, 기술적인 솔루션이 있는지 확인해 보기 위해 물리적 지식을 이용할 수 있습니다. 현재 BRDF의 경우, 재질 매개 변수들이 직교 매개 변수였다면 더 나았을 것이라는 문제가 있고, 거칠기를 변화시킴에 따라 이미지가 어두워지는 현상은 바람직하지 않습니다.

그렇다면 물리학이 도움이 될까요? 이미지가 어두워지는 것이 물리적으로 적절한 현상일까요? 적절한지 여부를 어떻게 테스트할 수 있을까요? 답은 용광로입니다. GGX로 코팅된 금속성 개체를 조명이 균일한 환경에 방치하고 어떤 현상이 일어나는지 살펴봅시다.

빛이 표면에 닿으면 미세 표면에도 닿습니다. 프레넬 효과에 따라 미세표면은 빛의 일부는 반사하고 다른 일부는 굴절시킵니다. 이 표면이 금속성이라고 가정하면, 물리 법칙에 따라 굴절된 빛은 표면의 ‘내부’로 들어가서 흡수된 후 다시는 나오지 못합니다(그대로 열로 변환됩니다).

심지어 용광로 안에서도 에너지의 일부가 흡수되면서 금속성 객체는 색을 띠기 마련입니다. 이때 미세표면이 빛을 전혀 흡수하지 않고 모두 반사하게 만들면 어떨까요?

이는 f0을 1로 설정함을 의미합니다. (프레넬은 미세 표면이 얼마만큼의 빛을 산란시키는지 제어하는 것임을 명심하세요). 이제 어떤 현상이 일어나는지 살펴봅시다.

개체가 아직 하얀색을 띠지 않습니다. 무언가 잘못된 거죠. 궁금증이 생긴 사용자라면, “무엇이 잘못되었는지 어떻게 아나요? 아마 어떤 방향으로는 더 많은 빛이 산란되고, 어떤 방향으로는 덜 산란되는 것 아닐까요?”라고 물을 수도 있습니다. 정답을 추측하는 것이 언제나 쉽지만은 않습니다.

대신 카메라에서 시작하는 빛의 경로가 어떤 모습인지 생각해 봅시다. 빛은 한 개 또는 수많은 미세표면에 닿아 반사되어 결국 용광로 환경에 도달하게 됩니다. 그리고 언제나 일정한 양의 에너지를 분출하게 됩니다.

이 에너지 중에서 얼마만큼이 카메라에 도달할까요? 바로 전부 다입니다. 현재 설정값에 따라 빛이 닿는 미세표면의 수와 상관없이 모든 에너지가 반사되어야 합니다. 모든 빛의 경로가 결국 카메라에 이르게 됩니다.

그러므로 위의 이미지는 완전히 하얀색을 띠어야 합니다. 그런데 그렇지 않기 때문에 수학적인 문제가 있다고 판단한 것입니다.

BRDF를 잘 아는 사람은 미세표면 모델에서 어떤 미세표면들이 다른 미세표면들을 폐색하는지 모델링하는 마스킹-섀도잉 가시성 함수가 있다는 것도 알고 있을 것입니다. 하지만 이렇게 폐색하는 미세표면이 그 자체로 미세표면이라는 사실을 모델링 시 고려하지 않기 때문에, 빛은 계속 반사되다가 이탈하게 됩니다.

이것이 바로 다중산란 모델로 개선할 수 있는 문제입니다. Kulla와 Conty의 GGX를 용광로에 넣으면, 거칠기와 상관없이 빛을 완전히 반사하는 재질을 갖춘, 완전히 지루하며 완전히 정직하게 하얀색을 띠는 이미지가 만들어집니다.

그러나 Kulla의 모델은 간단하지 않습니다. 보통 이런 사소한 문제 때문에 이용하게 되는 일도 없습니다. 그렇다면 더욱 간단한 솔루션을 개발할 수 있지 않을까요? 주어진 거칠기와 시야각에서(픽싱 f0=1로 다시 설정) BRDF가 용광로에서 분출하는 빛의 양을 알 수 있다면? 이 값을 가지고 BRDF를 정규화할 수는 없을까요?

스포일러: 할 수 있습니다. 그것도 쉽게. 널리 쓰이는 분할 합 이미지 기반 라이팅 근사화용의 룩업테이블에서 최신 엔진의 이 ‘용광로’ 값이 이미 존재합니다.

분할 합 테이블은 ‘용광로 속 BRDF'(방향 알베도 또는 방향 반구상 반사율이라고도 불림)를 가져다가 프레넬 f0 값에 적용할 스케일과 바이어스(추가) 팩터로 변환시킵니다.

지금은 f0=1를 바탕으로 하여 정규화를 하는 경우이므로, BRDF 로브를 바이어스(거칠기, ndotv) + 스케일(거칠기, ndotv)에 대해 하나씩 스케일링할 수 있습니다. 결과는 다음과 같습니다.

거칠기가 높으면 에너지의 일부를 돌려받을 수 있습니다. 용광로에서 테스트를 하면, f0=1에서 적절한 하얀색을 띠게 됩니다. 하지만 Kulla의 모델과는 다릅니다. 특히 색이 거친 재질에서처럼 채도가 높지 않습니다. 왜일까요? 이 문제를 미리 연구한 사람이라면 답을 알고 있을 것입니다.

적절한 다중산란은 빛이 표면에서 이탈하기 전에 더 많은 미세표면에 도달하여 더 많은 색이 들어가므로(색의 파워를 하나 더 높이면 채도가 더 높은 색을 얻을 수 있습니다) 채도가 높아집니다. 그러면 이것이 물리학적으로 잘못되었지만 우리가 실시한 테스트에서는 올바른 이유는 무엇일까요?

채도 증가를 시뮬레이션하지 않으면 에너지를 절약할 수 있지만, 우리는 여기서 BRDF 파라미터의 개념을 바꾸었습니다. 우리의 ‘무지한’ 다중산란 BRDF에서 f0의 ‘의미’란 Kulla의 모델과 동일하지 않습니다. 우리의 테스트에서는 다른 알베도 결과가 나왔지만, BRDF 함수 자체는 여전히 에너지를 절약합니다. 파라미터가 다를 뿐입니다.

더 중요한 것은 우리가 더 나은 파라미터들을 가지고 있다는 점입니다. 우리의 목표를 상기해 보세요. 물리학을 위한 물리학을 하는 것이 아니라 이미지를 만들기 위해 물리학을 이용하는 것입니다.

파라미터들의 직교성을 높이면, 아티스트들이 높은 거칠기에서 BRDF를 인위적으로 ‘더 밝게’ 할 필요가 없습니다. 만약 ‘보다 올바른’ 솔루션(이와 관련하여 Narkowicz의 최근 게시물이 매우 유익합니다)을 선택한다면, 다른 종속성 값을 추가할 수 있습니다. 그러면 재질을 어둡게 하는 대신 거칠기로 색의 채도를 높일 수 있습니다(이 방법은 사실 역효과입니다). 이 방법이 효과적인 시나리오들을 생각해 볼 수도 있지만, 우리의 경우에는 언제나 틀린 방법이라고 생각합니다.

채도 증가를 시뮬레이션하고자 하는 경우, 쉬운 방법이 몇 가지 있습니다. 가장 ‘무지한'(간단한) 방법으로, BRDF를 1+f0*(1/(바이어스(거칠기, ndotv) + 스케일(거칠기, ndotv)) – 1)만큼 스케일링하여 아래와 같은 결과를 얻습니다.

이것은 Kulla의 솔루션에 가깝습니다. 이미지에 드러나지는 않지만 어째서 Kulla의 근사값이 더 나은지 궁금하시다면, 우리의 이미지가 상호성을 고려하지 않기 때문이라 할 수 있습니다.

Sony Imageworks에게는 중요한 사안일 수 있습니다(특정 오프라인 경로 추적 빛 이동 알고리듬은 이를 필요로 하기 때문입니다). 하지만 우리의 경우와는 상관이 없습니다.

이제 우리가 만족할만한 근사값을 구했으므로, 한 단계 더 나아가 우리의 테스트가 어떻게 진행되는지 살펴볼 수 있습니다. 공식은 이미 있지만 일부 룩업테이블들이 결정적으로 중요합니다.

이는 큰 문제가 아닙니다. (어차피 이미지 기반 라이팅을 위해 이 룩업테이블들은 필요합니다.) 그러나 텍스처 페치를 추가하고 수학적 값들을 항상 다시 확인해야 합니다. 따라서 우리가 사용하는 1/[바이어스(거칠기, ndotv) + 스케일(거칠기, ndotv)] 함수를 시각화해 보도록 합시다.

놀랍게도 매우 간단합니다. 너무 간단한 나머지 답을 구하기 위한 정교한 툴도 필요하지 않습니다. 바로 1 + 2*alpha*alpha * ndotv입니다. 훌륭하죠.

올바른 정규화 팩터(회색 표면)과 비교한 근사화

이 용광로 테스트에는 약간의 오류가 있다는 것을 알 수 있습니다. 하지만 적절한 다항식 피팅으로 이 문제를 개선할 수 있습니다. (위의 공식에서 ‘2’와 ‘1’이 최선의 상수가 아님을 알게 됩니다.) 하지만 무엇이 ‘최선’인지 정하는 일은 그 자체로 문제입니다. 정규화 함수에서 평균 제곱 최소화는 바람직하지 않기 때문입니다. (결과로 나올 이미지, 지각적 척도, 어떠한 각도가 중요한지 등을 고려해야 합니다.) 이미 이렇게 사소한 수정을 하는 데 너무 많은 시간을 소모했습니다. 게다가 실제로 렌더링된 이미지는 테이블 기반 솔루션과는 구분하기가 매우 어렵습니다.

이제 ndotv에서 종속성을 빼고 더욱 간소화하여 어떠한 결과를 얻을 수 있는지 알아봅시다. 이 경우 1+alpha*alpha가 꽤 효과적임을 알 수 있습니다.

곱셈 팩터를 BRDF에 적용하여 높은 거칠기에서 이미지를 더 밝게 하면 됩니다.

물론 이 방법도 오류를 더 발생시키지만, BRDF 모양이 변하는 것을 볼 수 있습니다. 거친 표면의 지표각에서 더 많은 에너지를 얻을 수 있지만, 각자의 필요에 따라 지금 이미지로도 충분히 만족할 수 있습니다.

하이라이트에 과소 노출. 더 간단한 근사화를 진행하면 빛을 더 잃을 수도, 더 얻을 수도 있습니다.

이 글의 정보가 많은 도움이 되었으면 좋겠습니다. 물론 실제 세계의 물리학을 완벽하게 시뮬레이션하는 그래픽에 주력하는 것도 좋지만, 이렇게 편법을 쓰는 것도 가능합니다. 가끔은 성능, 간소화 또는 단순한 귀찮음 등의 이유로 편법이 올바른 답이 될 수도 있습니다.


Roblox Corporation이나 이 블로그는 특정 회사나 서비스를 홍보하지 않습니다. 또한 블로그에 포함된 정보의 정확성, 신뢰성, 완전성에 대하여 어떠한 보장이나 약속도 하지 않습니다.

이 블로그 게시물은 Roblox 테크 블로그에 수록된 글입니다.