주의 : 잘못된 내용이 있을 수 있으므로 이상하면 참고자료를 참조하세요.


[ PBR 이란 무엇인가 ] 11. UE4 GI : Sky Light

UE4 IBL 의 종류

일단 이미지 소스를 광원으로 사용한다면 그것은 IBL 이라 할 수 있습니다. UE4 에서의 IBL 은 Sky Light, Reflection Environment( Box Reflection Capture, Spehre Reflection Capture ), Ambient Cubemap( Post Process Volume ) 등이 있습니다. 오늘은 Sky Light 에 대해서 다뤄 보도록 하겠습니다.

주의 : 여기에서는 Stationary 환경을 중심으로 설명하도록 하겠습니다.

먼저 각 light 요소들의 영향력을 평가하기 위해 사용할 옵션들에 대해서 설명드리도록 하겠습니다.

Viewport 의 "Show" 풀다운 메뉴에는 "All Show Flags" 라는 섹션이 있습니다. 거기에 있는 "Light Types" 메뉴와 "Lighting Components" 메뉴를 사용해서 기능을 on/off 하면서 결과를 살펴 볼 것입니다.

그림1. "Light Types" 옵션과 "Lighting Components" 옵션.

Sky Light 란

아웃도어 환경을 고려하는 개발자라면 가장 먼저 배치하는 것이 direcitonal light, sky sphere( atmostpheric sky ) 같은 요소일 것입니다.

Sky sphere 같은 경우에는 directional light( 일반적으로 태양 ) 에 의한 Rayleigh scattering 과 Mie scattering 을 처리합니다. 이것을 IBL 소스로 쓴다면 매우 좋겠죠. 하지만 보통 그런 개체를 구현할 때 IBL 을 고려하고 만들지는 않습니다.

그래서 Sky sphere 를 IBL 로서 사용할 수 있는 방법이 필요합니다. 이를 도와 주는 액터가 바로 Sky Light 액터입니다. Mode 툴바에 보면 "Lights" 카테고리에 "Sky Light" 액터가 있습니다. 이를 씬에 배치하면 됩니다. 이때 액터의 위치는 대충 설정해도 됩니다. 그 이유는 뒤쪽에서 설명하도록 하겠습니다.

SkyLight 를 배치했을 때와 그렇지 않았을 때의 차이는 매우 큽니다. "Light Types >> Sky Lighting" 을 껐다가 켜 보면 그 차이를 볼 수 있습니다. 그림자가 진 영역에 대해서 "Sky Light" 성분이 반영되는 것을 알 수 있습니다.

 

 그림2. 이미지 슬라이더가 보이는 경우에는 왼쪽이 SkyLight 없을 때이고 오른쪽이 SkyLight 있을 때임. 이미지 슬라이더가 안 보이는 경우에는 위쪽이 SkyLight 있을 때이고 아래쪽이 SkyLight 없을 때임.

Sky Occlusion

그런데 SkyLight 를 배치할 때 한 가지 주의할 점이 있습니다. SkyLight 의 차폐 성분은 Lightmass 빌드시에 SkyOcclusion 이라는 아틀라스 텍스쳐에 포함되므로 Lightmass 를 빌드하기 전까지는 차폐 성분이 반영되지 않습니다.

그림3. Lightmass 의 SkyOcclusion.

그러므로 Lightmass 빌드 전에 박스를 옮겨 보면 그림4 처럼 차폐 영역에 SkyLight 가 그대로 뭍어 나오는 것을 알 수 있습니다.

그림4. Lightmass 빌드 전에는 SkyLight 에 대한 차폐가 발생하지 않음.

하지만 Lightmass 를 빌드하면 그림5 처럼 차폐된 영역에 SkyLight 가 들어 오지 않습니다.

그림5. Lightmass 빌드 후에는 SkyLight 에 대한 차폐가 발생함. 주의 : Preview 빌드에서는 샘플 개수의 부족으로 차폐가 제대로 반영되지 않을 수도 있습니다.

UE4 에서 SkyOcclusion 은 벤트노멀( Bent-Normal )과 입체각( Solid-Angle )을 사용해서 계산됩니다. 입체각이 뭔지 기억이 안 나시는 분은 [ 3. 빛의 감쇠 ] 를 참조하세요. 벤트노멀이라는 것은 어떤 벡터들의 평균벡터를 의미합니다.

그림6. Bent Normal. 출처 : How could I use bent normal map.

그림6 에서 보이듯이 서피스의 어떤 점으로부터 반구내에서 사방으로 레이를 쏘면 다른 서피스와 충돌하지 않고 나아가는 레이들이 있습니다. 그러한 레이들의 벡터들을 모두 더해서 평균을 내면 BentNormal 이라는 것이 나옵니다. 그리고 BentNormal 을 중심으로 얼마나 열려있는지를 구할 수 있고 그것을 입체각 단위로 저장합니다.

그러면 그림7 에서와 같이 어떤 점에서 하늘에 대한 차폐 정도를 알 수 있죠. 그러면 BentNormal 은 specular reflection 과 diffuse reflection 을 위해 이미지를 샘플링하기 위한 중심벡터가 되고, 입체각은 차폐 정도를 판단할 수 있는 기준이 되죠.

그림7. 여러 지점에서 BentNormal 과 SolidAngle 을 구함. 붉은색, 녹색, 보라색 순으로 차폐 정도가 덜함을 알 수 있음.

SolidAngle 을 알게 되면 반구의 면적이 pi 이므로 SolidAngle / 2pi 를 하면 [0, 1] 범위의 값이 나오며, 그것이 SkyVisibility 가 되는 것입니다 .SkyOcclusion 아틀라스 텍스쳐의 rgb 채널에는 BentNormal 이 a 에는 1 - SkyVisibility 가 들어 갑니다( 사실 실제 Lightmass 구현에서는 일일이 SolidAngle 을 구하지는 않고, 차폐된 ray 의 개수를 사용해 occlusion 을 구합니다. 여기에서는 설명의 목적으로 SolidAngle 을 사용했으나 개념상으로는 큰 차이가 없습니다. 정확도의 차이는 있겠지만 비슷한 비율이 나옵니다 ).

Indirect specular reflection & indirect diffuse reflection

SkyLight 의 경우에는 indirect specular reflection 과 indirect diffuse reflection 을 모두 반영합니다. 씬에 크롬볼과 화이트볼을 하나 배치해 보도록 합시다. 그리고 SkyLight 성분을 확실하게 보기 위해서 "Light Types >> Directional Light" 를 off 합니다. 그리고 나서 "Light Types >> Sky Lighting" 을 on/off 해 봅니다.

그림8. SkyLight 가 반영된 상태.

그림9. SkyLight 가 반영되지 않은 상태. SkyLight 를 제외한 reflection 성분은 나중에 이야기할 Reflection Capture 로부터 온 것입니다.

다음으로는 SkyLight 를 켠 상태에서 "Light Components >> Diffuse" 와 "Light Components >> Specular" 를 on/off 해 봅니다.

그림10. Diffuse 만 활성화. 크롬볼은 metalic 이 1 이고 roughness 가 0 이므로 전혀 diffuse 성분을 안 먹습니다. 원래 완전한 금속은 diffuse 가 0 이기 때문인데 그 이유에 대해서는 시리즈의 뒷부분에서 설명하도록 하겠습니다.

그림11. Specular 만 활성화. 화이트볼은 metalic 이 0 이고 roughness 가 1 이지만 fresnel 효과에 의해 약간의 specular 를 먹습니다. 그 이유에 대해서는 시리즈의 뒷부분에서 설명하도록 하겠습니다.

Capture

이제 directional light 와 sky sphere 의 설정을 변경해서 초저녁 환경을 만들어 봅시다. 하지만 Sky Light 의 capture 는 변경되지 않습니다.

그림12. 환경을 변화시켜도 SkyLight 에 반영되지 않음.

 이때 빠르게 분위기를 확인하고자 한다면 SkyLight 액터의 "Sky Light" 카테고리에서 "Recapture" 를 누르시면 됩니다.

그림13. Recapture 를 통해 환경 반영.

하지만 그림13 에서 크롬볼에 반사되는 일부 메쉬들이 여전히 파란색 스카이 컬러를 먹고 있는 것을 알 수 있습니다. 앞에서 언급했듯이 specular 성분 중에서 Sky 를 제외한 다른 부분은 Reflection Capture 로부터 온 것입니다. Reflection Catpure 에서 "Update Captures"` 를 실행해 줘야 모든 specular 성분에 Sky 색상이 제대로 반영됩니다.

Capture 대상

여러분은 이 시점에 "어떤 대상을 SkyLight 로 캡쳐하는 것일까" 궁금해 하실 겁니다. 사실 대상이 정해져 있는 것은 아닙니다. SkyLight 액터가 배치된 위치로부터 일정 거리 이상에 존재하는 요소들을 Sky 로 취급합니다. SkyLight 액터의 "Light" 카테고리에는 "Sky Distance Threshold" 라는 속성이 있습니다. 이 값을 조정하시면 됩니다.

SkyLightActor 를 액터를 벽에 붙여 놓고 "Sky Distance Threshold" 를 1.0 으로 설정하고 "Recapture" 를 하면 그림14 와 같은 결과를 얻을 수 있습니다.

그림14. Sky Distance Threshold 를 작게 잡았을 때의 결과. 하늘이 나와야 할 부분에 벽이 나오는 것을 확인할 수 있습니다.

이 값은 기본적으로 150000 센티미터( 1.5 KM )로 잡혀 있습니다. 매우 큰 값이므로 SkyLight 액터를 아무 곳에나 배치해도 상관이 없는 것입니다. 만약 여러 분이 SkyLight 에 하늘 이외의 원경이 반영되었으면 좋겠다고 생각하신다면 이 문턱값을 조정하시면 됩니다. 물론 SkyLight 액터도 적절한 위치에 배치해야겠죠.

Sky Light 의 개수

이제 이 시점에서 여러 개의 Sky Light 를 배치해 다양한 효과를 내 보겠다는 생각을 하시는 분이 있을 수 있습니다. 하지만 현재 구현에서는 하나의 월드에 여러 개의 SkyLight 를 사용하는 것이 불가능합니다. Lightmass 빌드를 하면 다음과 같은 에러를 확인할 수 있습니다.

그림15. 여러 개의 SkyLight 사용시 lightmass 에러 발생.

+ Recent posts