GI(Global Illumination)는 실제 자연광처럼 표면에서 반사되는 빛까지 모두 표현하는 시스템을 말합니다.
https://docs.unity3d.com/560/Documentation/Manual/GIIntro.html
정의부터 알겠지만 GI를 실시간 라이팅으로 구현할 경우 비용이 크다.
하지만 GI를 구현하지 않을 경우 아래처럼 그려지는 화면의 퀄리티가 눈에 띄게 낮아진다.
유니티 역시 예외는 아니며, 최대한 성능을 아껴가며 GI를 구현할 수 있는 솔루션을 몇 개 제시해놓았다.
바로 `라이트 맵`과 `라이트 프로브`이다.
(사실 리얼타임 GI도 있다고 함, 근데 제약 사항이 많고, 우선... 이거 먼저 하고 나중에)
라이트 맵
적용하려면?
라이트 맵은 그림자 맵처럼 텍스처로 라이트를 구워내는 형식을 말한다.
당연히 Dynamic한 오브젝트엔 적용되지 않아서, Static 플래그가 체크된 오브젝트에 한하여
라이트 맵이 Bake된다.
Bake 시 적용되는 라이트는 Baked 혹은 Mixed Mode의 라이트이다.
(Mixed는 동적 오브젝트에도 적용되며, 맵을 구울 때도 적용된다.)
구운 라이트 맵을 오브젝트에 적용하기 위해선 Contribute GI 플래그를 체크하고
Receive GI를 Light maps로 하고... (2021.3.8f1 기준)
외부 툴에서 받아온 FBX 등인 경우... 아래를 체크해 UV 채널을 하나 더 열어줘야 한단다.
외부 툴에서 UV 채널을 열어놓은 경우엔 그럴 필요 없다고 함
아무튼 메시에 사용될 텍스처와 라이트 맵 텍스처를 받아들일 UV 채널 두 개를 열라는 뜻 같음
좀 더 자세한 용법은 아래를 참고하면 될 것 같다.
https://learnandcreate.tistory.com/524
라이트 맵의 해상도 설정은 어떻게?
Resolution 40 : 라이트 맵이 1 유닛 당 40개의 텍셀을 가지도록 라이트 맵을 제작
Max Lightmap Size 1024 : 1024 x 768 사이즈로 라이트 맵을 제작
Resolution이 높으면, 라이트 맵의 해상도가 높아져야 합니다. (텍셀이 많아지니까)
그러니까 Size를 낮게, Resolution을 높게 설정하면, 라이트 맵이 여러 장이 됩니다.
이게 무슨 소리냐면, 라이트 맵 해상도가 크면 > 필요 대역폭 크기 커짐
그렇다고 해상도를 낮춰서 라이트 맵 개수를 늘리면 > 드로우 콜 배칭이 안됨
와 같은 트레이드 오프에 처하게 된다는 뜻
모바일은 GPU 대역폭이 작으니까 개수를 늘리는 게 나을 수도 있는 등 잘 고려해서 쓰면 될 것 같다.
Directional은 빛의 방향을 고려하여 라이팅 환경을 베이크하는 모드이다.
그렇기 때문에 오브젝트의 노말맵을 적용할 수 있다.
이 상태에서 베이크하게 되면,
요렇게 빛 방향에 대한 라이트 맵 하나가 더 만들어 진다. (메모리 소모 및 픽셀 쉐이더 연산 추가가 예상됨)
Baked랑 Mixed 라이트의 베이크 시 차이는 정말 없나?
있다.
요걸 체크하면 Mixed 라이트가 베이크될 GI 안에 포함된다.
Baked Indirect는 GI만 라이트맵에 반영, 그림자와 Directional Light는 리얼타임에 반영해서 사용
> 그림자가 실시간 연산되기 때문에 무거울 수 있으나 퀄리티가 좋음
Subtractive는 GI, Directional Light, 그림자 모두 라이트맵에 반영해서 사용
> GI 구역과 다이나믹하게 반영한 그림자의 퀄리티가 달라서 어색할 수 있음
Shadow Mask는 라이트 맵에 GI, 그림자를 반영하고, Directional Light는 리얼타임에 반영함
> 그림자를 실시간 연산하지 않으나, 픽셀 쉐이더에서 리얼 타임 그림자들과 자연스럽게 합성하는 과정을 거치기 때문에,
그림자가 어색하진 않음, 그림자 텍스처만큼 공간이 필요함
또한 Distance Shadowmask를 이용해, 특정 거리 안에선 쉐도우 맵, 그 밖에선 Shadowmask를 이용하여 처리할 수도 있음
라이트 프로브
라이트 맵은 static 오브젝트에 대한 라이트를 텍스처로 구워 픽셀 쉐이딩 단계에서 처리하여 최적화하는 방법이다.
그에 반해 라이트 프로브는 dynamic 오브젝트에 대한 최적화 방법이다.
dynamic 오브젝트의 경우, Baked Light와 일부 Mixed Light의 라이트 맵에 영향을 받지 않기 때문에,
영향을 받은 static 배경 오브젝트와 어울리지 않을 수 있다.
라이트 프로브는 이에 대한 솔루션이며, 빛이 지나가는 빈 공간의 지점을 저장하고, 이를 Dynamic Light에 반영하는 방식이다.
Probe 하나에 9개의 float을 색상 채널별로 저장해서 float 27개를 저장한다고 한다.
비압축된 32bpp 텍스처의 6.75 픽셀 정도의 크기이고,
이 작은 크기의 데이터를 구면 조화 함수를 통해 텍스처처럼 사용한다는 느낌
이게 먼진 모르겠고... 암튼 작은 크기로 다이나믹 오브젝트에 Bake된 라이트를 반영할 수 있다는 게 중요하다.
물론 작은 크기만큼 디퓨즈 라이팅을 제외한 라이팅은 표기할 수 없다고 한다.
(디퓨즈는 난반사, 스페큘러는 정반사라고 보면 될 듯)
아무튼 저 Probe Group 영역 근처에 있는 Mesh Renderer는 값을 보간받아 라이트가 적용된다.
'Unity' 카테고리의 다른 글
[Unity] Render Texture와 Raw Image 활용 (0) | 2022.09.19 |
---|---|
[Unity] 텍스처 (그래픽스 최적화 스타트업) (0) | 2022.08.27 |
[Unity] 그림자 (그래픽스 최적화 스타트업) (0) | 2022.08.08 |
[Unity] 포워드, 디퍼드 렌더링 (0) | 2022.08.01 |
[Unity] 드로우 콜과 배칭 (그래픽스 최적화 스타트업) (0) | 2022.07.25 |