[2016.06.02 작성]
홍혜종, 최우성
유니티 version : Unity 5.1.2f1
아래 설명은 위 버전을 기준으로 함.
[최근 수정일: 2018.11.29]
백인선
유니티 version : Unity 2018.2.10f
아래 설명을 위 버전에 맞춰서 수정할 예정
Lighting 기법의 종류
1. Realtime Lighting
- 실시간으로 빛을 계산한다.
- 최적화 없이 냅다 실시간으로 계산하기 때문에 원하는 결과물을 얻을 수 있다.
- 근데 무겁다.
2. Light Mapping
- 빛을 받은 듯이 보이게 텍스쳐를 입혀 놓는다. (Bake, 굽는다고 표현한다.)
- 라이트 계산이 아닌 텍스쳐를 입히는 것이라 가볍다.
- 문제는 물체가 움직이면 라이트를 다시 계산하는게 아니기 때문에 현실성이 떨어지는 결과를 낳는다.
(그림자가 따로 논다던가..)
- Light Map을 너무 많이 적용하면 오히려 텍스쳐 무게로 인해 더 무거울 수 있다.
3. Light Probe
- Light Mapping이 표면(Texture)에 닿는 빛에 대한 정보를 담는 거라면, Light Probe는 빈 공간에 정보를 담는 것이라 할 수 있다.
- 다음 사진과 같이 빈 공간에 점들(Probe)을 지정해서 그 곳에 빛의 정보를 굽고 그 정보를 가지고 계산을 실시한다.
- 무한히 확산한 빛을 계산하는 것보다 가볍다.
- 대신 각각 Probe에서 값을 가져와 계산하기 때문에 물체간의 간섭이 안된다.
=> 즉, 그림자가 안 나온다..
- Probe들을 너무 촘촘하게 배치하면 유사 Realtime Lighting이 되버려 무거워질 수 있다.
Light Mapping을 해보자.
하기에 앞서서..
다음과 같은 경로로 Lighting 창에 들어가면 가장 아래에 Auto가 체크가 되어있고 Build버튼이 있다.
Auto가 체크되어 있으면 작업 중 Scene안의 오브젝트가 움직일 때마다 빛을 새로 계산해줘서 Scene창에 띄워준다.
근데 이게 묘하게 끊겨서 귀찮다.. 그게 싫으면 체크를 해제해주자.
1) 라이트 매핑을 할 오브젝트의 Static을 체크한다.
※ Static : 정적(움직이지 않는) 오브젝트들에 사용되면 좋다.
오브젝트 위치변화로 인한 데이터 무효화가 일어 날 일이 없다는 것을 전제로 사용할 것.
렌더링 시 여러 정적 오브젝트를 batch라고 불리는 하나의 오브젝트로 결합하여 최적화.
2) Light에서 Mode를 Baked로 바꾸자.
Realtime : 실시간
Baked : 베이크(미리 연산)
Mixed : 자동으로 리얼타임과 베이크 전환
끝... (음?)
그런데..
요게 Realtime Lighting 그리고 요게 방금한 라이트맵핑....
결과물이 시원치가 않다.
색 상태도 뭔가 거무죽죽하고... 그림자도 뿌옇게 됐달까...
원본과 너무 다르다...
손을 봐야한다.
아까 열었던 Light창을 다시 봐보면
요런 놈이 있다.
여기서 Global Maps과 Object Maps은 빛을 계산해서 Object에 Mapping할 Texture을 보여준다.
(Global은 전체 Texture를, Object Maps은 선택한 Object의 Texture를 보여준다.)
이런게 있다고 알아두고 본격적으로 Scene안을 보자.
Scene을 선택하고 주욱 내리다보면 요런 놈이 있다.
여기서 Lightmapping을 설정할 수 있다.
Lightmapper: Mapping할 방식을 정해준다. Enlighten과 Progressive Lightmapper가 있다.
ㅁ Enlighten: 미리 계산된 실시간 GI를 이용하여 간접조명을 계산하는 법.
ㄴ 조명만 변경하면 새 라이트맵을 꽤 빨리 만들 수 있다.
ㄴ 사용자가 베이크만 하려 할 때에는 모는 UV 레이아웃 제약이 적용되는 단점이 있다.
ㅁ Progressive Lightmapper: Unity 에디터에서 Progressive Update 방식으로 베이크된 라이트맵과 라이트 프로브를 제공하는 경로 추적 기반의 방식.
Scene을 새로 만들면 Default값으로 설정 되어 있다.
ㄴ Enlighten보다 신기술
ㄴ 짧은 준비 단계(지오메트리 및 인스턴스 업데이트, G 버퍼 및 차트 마스크 생성)를 거쳐 결과물을 빠르게 생성할 수 있다.
ㄴ 새 중간 결과가 준비되는 즉시 새 라이트맵과 라이트 프로브가 표시되므로 매우 빠른 워크플로가 가능
ㄴ 아직 개발 중이다.
새 기술이 있다는데 한 번 만져보자. (신기술 핡짝)
Prioritize View: 활성화하면 씬 뷰의 카메라 절두체에서 현재 보이는 Texel(Texture의 화소)을 우선적으로 처리하게 된다.
Direct Samples: 각 Texel에서 쏜 샘플(경로)의 수로 Progressive Lightmapper가 직접 조명 계산에 사용하는 샘플 수를 제어.
- 값을 키우면 품질은 향상되지만 베이킹 시간이 길어진다.
Indirect Samples: 각 Texel에서 쏜 샘플(경로)의 수로 Progressive Lightmapper가 간접 조명 계산에 사용하는 샘플 수를 제어.
- 야외 같은 경우 100 정도면 충분하지만 실내 장면의 경우 값을 더 키울 필요가 있다.
Bounce: 경로를 추적할 때 수행할 간접 수신의 수. (일반적으로 2번이면 충분, 일부 실내 장면이라면 더 필요할지도..)
Filtering: 노이즈를 제한하도록 라이트맵 포스트 프로세싱을 설정.
자동으로 시키거나(Auto), 직접 손대거나(Advanced), 아예 안 할 수 있다(None).
Lightmap Resolution: Lightmap에 사용할 단위당 Texel 수를 지정 (Default: 10).
Lightmap Padding: Lightmap의 분리된 Shape의 간격을 조절 (Default: 2).
Lightmap Size: Lightmap의 크기 조절 (Default: 1024).
Compress Lightmaps: Lightmap의 압축여부를 설정합니다.
Ambient Occlusion: 표면의 상대적 밝기를 제어할 수 있는 설정. 체크하면 밑에서 값을 조절 할 수 있다.
값이 높을수록 폐색 영역과 완전 조명 영역 사이의 대비가 커진다. (뙤얕볕 아래와 동굴 안의 차이라고 보면 될 듯..)
Directional Mode: 물체 표면의 각 점에서의 입사광에 대한 정보를 저장 여부를 설정.
- Normal을 쓸 생각이 없다면 꺼두자. Normal만 따로 저장하는 Texture가 생겨서 용량이 2배가 돼 버린다.
오른쪽이 Normal Vector를 담아놓은 Texture. Lightmap이 두 개가 됐다.
Indirect Intensity: 실시간 및 구운 Lightmap에 저장된 간접 조명의 밝기를 조절.
Albedo Boost: 표면 간의 튕겨나오는 광량을 조절.
이걸 막 만지다보면 얼추 비슷하게 만들 수 있을 거 같다.
우선 그림자가 너무 흐리니 Lightmap Resolution값을 키우자.
어두칙칙한 밝기는 빛의 세기 자체를 키우면 된다.
Lightmapping 결과
ㅇㅅㅇ)b 그럴싸해졌다.
지금까지 큐브를 띄우고 Lightmapping을 해봤다. (중간에 교회가 보인건 기분탓이다. 아무튼 기분 탓이다.)
그럼 이제 외부에서 모델 하나 받아와서 Lightmapping을 해보자.
Asset Store에서 Model 쳤더니 바로 나온 녀석이다.
무료더라.. 얘로 가자
Import해서 Model을 받아오고 Hierarchy에 올려준 다음에 static으로 처리하고
UV texture가 4096 x 4096이라니까 설정에서도 똑같이 바꿔줘 보자.
그 다음 빛을 구우면..
...?
그림자 상태가 개판이다..
Lightmapping이라는게 Texture를 구워서 Object에 입히기 때문에
겹치지 않는 또 다른 UV좌표가 필요하다.
유니티 기본도형은 유니티가 알아서 UV좌표를 펴줘서 상관은 없지만
직접 만든 모델이라면 따로 펴지 않는한 이런 두번째 UV좌표가 없다.
고로 유니티 내에서 제공하는 기술로 직접 만들어 보자(라고 했지만 항목에 체크하면 끝이다).
Project창에서 Import한 모델을 선택하면 Inspector창에 이런게 뜬다
Lightmapping할 모든 모델에서 중간에 있는 Generate Lightmap UVs를 체크하자.
중간에 존재감을 과시하며 가로지르던 그림자가 사라졌다.
만약 결과가 영 마음에 들지 않는다면 Generate Lightmap UVs를 체크하면 생기는 Advenced의 값을 조절하자.
Hard Angle: 인접한 삼각형 사이의 각으로 기본값은 88도이다.
180도 설정 시 모든 모든 모서리가 매끄러워져 유기적 모델에 어울리고, 기본값 88도면 기계적인 모델에 어울린다.
Pack Margin: Mesh가 1024x1024의 Texture를 차지한다고 가정했을 때 인접 차트 간의 여백(Pixel 단위)을 뜻한다.
값이 클수록 마진이 커지지만 그만큼 차트에 필요한 공간도 커진다.
Angle Error: Sorce Geometry의 각도에서 가능한 최대 UV 각도의 편차값. 보통 Lightmapping시 문제를 피하기 위해서는 값이 상당히 낮아야 한다.
Area Error: Sorce Geometry의 영역에서 가능한 최대 UV 영역의 편차값. 보통 Lightmapping시 문제를 피하기 위해서는 값이 상당히 낮아야 한다.
가슴이 시키는데로 수정해보자.
앞서 말했 듯 Lightmapping은 Object 표면에 받는 빛을 미리 계산해서 Texture로 만들어 입히는 방식이다.
그래서 게임을 시작할 때 이 후로는 계산하지 않기 때문에
중간에 Light가 꺼져도 자체발광하는 현상이 일어나고 (오오 야광 오오)
물체를 움직이면 그림자가 물체를 거부하는 현상도 일어난다.
이러한 현상 때문에 Object가 움직일 필요 없는 배경 같은 경우는 상관 없겠지만,
움직이는 Object의 경우(주인공, 적 등등..) 주변 빛을 무시하고 굉장히 개성적인 빛과 그림자를 보여주게 된다.
그런 현상을 띄우고 싶다면 딱히 상관없겠지만 일반적으로는 다른 방법을 찾아야 한다.
Light Probe란 Lightmapping과는 다르게
Light 정보를 Texture에 굽는게 아닌 공간에 굽는 거다.
좀 자세히 말하자면
굽는 시점에서는 어느 공간에 지정된 한 점에 들어오는 모든 빛들을 미리 계산해 저장해 뒀다가
게임 내에서는 저장된 빛의 정보를 주변 Object로 뿌려주는 느낌이다. (라고 말해놨더니 더 어려워졌다..)
일단 한 번 만들어보자.
GameObject -> Light -> Light Probe Group
그러면 이런 동글동글한 노란 구슬들이 나타난다.
나중에 빛을 구을 때 이 구슬들에게 빛의 정보를 저장하게 된다.
Inspector 창에서 Edit Light Probes를 누르면 노란 구슬들을 조절할 수 있는 설정들이 활성화 된다.
Add Probe를 눌러 구슬들을 늘리고 적절하게 배치하자.
예제에는 격자무늬로 배치를 해보도록 하자.
짠
그리고 Light Probe를 통해 빛을 받을 동적 Object를 만들자
우리들의 친구 캡슐짱
캡슐의 Component 중 Mesh Renderer를 보면 Light Probes가 있다.
Blend Probes를 선택하면 이제 Light Probe를 받게 된다.
그러면 캡슐을 선택했을 때 현재 어떤 Probe의 영향을 받고 있는지 주변에 뜨게 된다.
요러면 끝!
..이긴 한데 여기까지하면 문제가 하나 남는다.
캡슐이 크기가 작아서 지금은 티가 안 나는데
만약에 덩치큰 평면이 나타난다면...??
.....????
전체가 까맣다...
오직 평면의 가운데 있는 저 점에서 주변 Probe의 값들을 받아 계산하고
그걸로 면 전체의 색을 정해주다보니 면이 커지면 저런 부자연스러운 현상이 일어난다.
이걸 해결해보자.
유니티 4.5 이후로 있는 기능인 Light Probe Proxy Volume(LPPV)라는 기능이 있다.
일단 바로 적용해보자.
Component에서 적용하고
여기서 Use Proxy Volume을 체크하자.
그러면..
짠
각각의 점들이 주변 Probe들의 정보를 받아 각 구역에서 계산을 실시해서
전체가 한번에 다 까매지거나 하얗게 되는 걸 막을 수 있다.
LPPV Component에서 설정을 통해 점의 밀도를 조절할 수 있고,
아예 수동으로 갯수를 조절할 수도 있다.