Featured image of post 삼품에서 실시간 라이트 여러개 사용하기 : 라이트맵 안만들기

삼품에서 실시간 라이트 여러개 사용하기 : 라이트맵 안만들기

삼품에서 퍼포먼스 저하 없이 실시간 라이트를 여러개 사용하기에 대한 연구
study of using dynamic lights with maintain performance in Three Kingdom project.

                                                                                                                     프로그램 2팀 테크니컬 아트디렉터 정종필

 

서론

이전의 디퍼드 렌더링에 대한 이야기는 기억하고 계실 겁니다.
잘 모르시면 아래 링크를 한번 읽어주세요 :)

http://intra.ndoors.com/center/board/view.asp?list_seq=210811&board_seq=313&readchk_flag=N

위 글의 요지는 디퍼드 렌더러를 강제 사용하고 있었고, 디퍼드 렌더러는 라이트의 계산을 빠르게 해 주는 장점이 있었으나 초당 수십번의 타겟 렌더 이미지 생성으로 , 기본사양 자체가 저사양에서 돌리기는 힘들정도로 올라간다는 얘기였습니다.
 
위키페이지:
http://en.wikipedia.org/wiki/Deferred_shading

<좌로부터 칼라 G 버퍼, Z 버퍼, 노말 G 버퍼.  이런 버퍼들이 조합되어 나중에 조명계산을 한번에 처리하기 때문에 지연렌더링 (deferred rendering) 이라고 불린다. >

<지연렌더링의 결과물>

그래서 삼품과 같은 저사양 목표 게임에서는 디퍼드 렌더러를 사용해서는 곤란하며, 포워드 렌더러로 가동시켜야 한다는 얘기였었습니다만, 전통적인 포워드 렌더러에는 치명적인 약점이 있었으니, 그것은 ‘라이트를 추가하면 추가할수록 기하급수적으로 느려진다’ 라는 것이었습니다.

본론

  1. 라이트 체계의 약점과 극복 방법

이 약점은 생각보다 큰 것이라, 컴퓨터 사양이 일정 이상이 되더라도 기하급수적으로 불어나는 라이팅 부하 때문에, 일정 수준 이상의 퀄리티를 보이는 게임을 만들기 위해서는 어쩔 수 없이 초기 기본 사양을 잡아먹는 한이 있더라도 라이트 연산의 부하는 더이상 증가하지 않는 디퍼드 렌더러를 선택할 수 밖에 없었습니다. 하지만 우린 아니지요. 저사양 목표라면 쓰면 안됩니다.

어쨌건 포워드 렌더러를 써야 하는 우리 게임의 상황에서, 다이나믹 라이트의 추가는 무척 힘든 일이었습니다. 사양을 낮추려고 폴리곤을 줄이고 텍스쳐를 줄였습니다만 라이트를 하나 추가할수록 엄청난 수치의 Draw call이 증가하면서 사양이 기하급수적으로 늘어나게 되어 버리므로 어쩔 수 없이 라이트 하나만을 사용 (다이렉트 라이트. 실제로 이렇게 라이트를 하나만 사용하는 방법은 많은 포워드 렌더링 게임에서의 오랜 숙명이었습니다) 할 수 밖에 없었습니다.

그래서 추가적 라이트 효과로 멋진 배경을 만드려면 어쩔 수 없이 라이트가 아닌 ‘맵핑’ 으로 라이트 효과를 내야 했었으며, 이것이 라이트맵입니다. 라이트맵은 맵핑이기 때문에 조명연산이 전혀 되지 않는다는 장점이 있지만, 텍스쳐 장수가 늘어나고 무엇보다 라이트맵을 굽는 (Baking) 작업 자체가 힘든 작업이며, 수정도 용이하지 않다는 단점이 있었습니다. 그나마 유니티의 라이트맵은 굉장히 편하지만 말이지요.

하지만 라이트맵이 만들기 힘들다고 안쓸 수 없는게… 위에서 말했듯 실시간 라이트를 하나 이상 추가하면 대단히 느려지고 (간단하게 2배 느려진다고 생각하셔도 무방할 정도) …

그래서 포기하고 있었는데..

그래서 이래저래 방법을 찾으며 옵션별 세부사항 정하다가 포워드 렌더링의 세부 문서를 발견하고 번역해 보게 됩니다.

http://intra.ndoors.com/center/board/view.asp?list_seq=213443&board_seq=313&page=1&search_option=&search_letter=&readchk_flag=I

그러자, 유니티의 포워드 렌더링에서는 라이트를 일반적 상식과 조금 다르게 처리한다는 것을 알 수 있었습니다. 라이트가 추가될 때 마다 무조건 한 pass (렌더링 한 사이클) 를 돌아야 했던 겜브리오와는 다르게, 라이트마다 조금씩 다르게 설정을 하는 것을 알 수 있었지요.

즉 라이트가 있을때 마다 pass가 무조건 도는게 아니라, pass를 돌 일정 개수의 라이트를 옵션에서 정할 수 있게 해 놓았다는 것입니다.

이것인 즉 Pixel Light Count .( 픽셀 라이트 카운트는 한 픽셀마다 라이트의 밝기를 계산하는 매우 정밀한, 그러면서 일반적인 라이트이며, 일반적으로 말하는 ‘조명 영향’은 이것을 의미합니다.)  옵션에서 지정한 만큼의 라이트만 픽셀 라이트로 계산하도록 하겠다라는 것이며, 지정된 그 수치를 벗어나는 라이트는 다시 2단계의 저급 라이트 - 가벼운 - 로 자동 변환해서 계산하게 됩니다.
즉 여기서는 지정된 수치 이상의 라이트가 추가되더라도 무조건 픽셀 라이트로 다 계산하지 않고, 일단 저렴한 버텍스 라이트로 4개까지는 더 버텨보다가 싸구려인 SH(구면조화함수) 라이트로 나머지는 전부 처리해 버린다고 합니다. 그러므로 실시간 라이트의 개수를 옵션에서 능동적으로 제어할 수 있다는 말인거죠. 물론 퀄리티는 좀 떨어지겠지만.

이거라면 …? 잘하면 라이트맵을 쓰지 않아도 현재 그래픽 디자이너 분들이 사용하는 다이나믹 라이트를 다 사용할 수 있을지도 모릅니다. 물론 어떤 단점도 분명 존재하긴 하겠지만 말입니다. 라이트맵 굽지 않고 그냥 라이트를 쓸 수 있다면 그게 어디입니까. 

  1. 실험.

그래서 이 이론을 그대로 실험해 보는 작업을 시작했습니다. 테스트할 맵은 현재 다이나믹 라이트가 10개 박혀있는 남만의 섹션1 던전. 크기는 크지 않지만 두 개의 디렉셔널 라이트와 함께 여러 개의 포인트 라이트가 박혀 있습니다.
이걸 그대로 사용하면, 즉 모두 픽셀라이트로 계산하도록 처리하면,

그림자도 없는 상태에서 드로우콜만 1300이 넘어갑니다 . 물론 이렇게 쓸 일은 없겠지요.

그래서 극단적으로 픽셀 라이트 카운트를 0로 떨어뜨려봤습니다. 라이트의 품질차이는… 살짝 느껴집니다만 스샷으로는 잘 모를 정도입니다.  이론대로라면 지금 상태는 픽셀라이트가 하나도 없고 버텍스 라이트 4개와 SH 라이트 6개로 바뀌어 있는 거겠죠.

그 증거는 드로우콜에서 나타납니다. 무려 273 !
이게 어느 정도냐고요?

픽셀라이트 10개로 풀어놓았던 상태에서, “라이트를 모두 지웠을때” 와 같은 퍼포먼스입니다.
즉 옵션만 낮춤으로써, 라이트를 모두 지운것과 같은 퍼포먼스를 얻을 수 있다는 얘기입니다.
정밀도가 좀 떨어지는게 보입니다만, 거의 상대비교를 해야 보일 수 있을 정도이므로 퀄리티에서 큰 걱정은 안해도 됩니다.

결론적으로 옵션에서 픽셀라이트 개수만 조절하면 라이트를 모두 없앤 것 정도까지의 퍼포먼스를 자유자재로 제어할 수 있다는 얘기입니다. 물론 그렇다고 해서 라이트가 마구 박아도 된다는 얘긴 아닙니다 :) 버텍스 라이트나 SH 라이트는 픽셀라이트에 비할바 없이 가볍지만 꼭 장점만 있는건 아니거든요.

  1. 단점.

일단 라이트맵과 비교해서의 단점은 : 그림자가 없습니다.
그림자를 켜면 되지 않겠냐고 하시겠지만… 픽셀라이트를 제거할 정도까지 옵션을 낮춘다는 말은 이미 그림자도 없앴다는 말입니다…. 그러므로 이걸 사용하게 되면 그림자는 없다고 보시면 됩니다.

그 다음의 단점은 : 배경 구성할때 좀 주의해야 합니다.

무슨 말이냐면,
이런 겁니다.

예를 들어 이 맵. 이런 맵 말이죠. 실내이고 어두워서 라이트의 맛을 한껏 낸 맵입니다. 아마도 라이트 효과가 안보이셔서 픽셀라이트 카운트를 7로 올려놓으셨는가 보군요.

이런 맵은 픽셀라이트 카운트를 0로 해버리면 무척 ‘플렛’ 하게 되어 버립니다. 아까 봤던 야외 배경처럼 라이트의 영향이 그렇게 강렬하지 않은 맵은 상관없는데, 이렇게 강렬하면 라이트의 갯수 제한이 이미지에 영향을 끼칩니다.

뭐 라이트를 1개나 2개 정도로 타협할 수도 있지만, 7개만큼의 효과는 나오지 않습니다.

그 이유는 " 한 오브젝트에 몇 개까지의 빛이 효과를 미칠거냐" (여기서의 빛은 정밀한 픽셀라이트를 의미합니다) 를 제한하는 이 옵션의 근본적 문제입니다.
좀더 극단적인 예를 볼까요.

예를 들어 이런 스타일. 굉장히 분위기있고 멋집니다. 분명 라이팅이 아니었으면 이렇게 멋진 장면을 나타낼 수 없었겠지요.
현재 라이트는 4개쯤 보이고 있습니다.

그런데 여기서 권장인 1개 정도로 제한해 버리면,
이런 현상이 나타날 수 있습니다. 이것은 왜 일어난 것일까요?


이것은 모델링된 오브젝트의 형태 때문입니다. 자 잘 보시면 저 길은 한 덩어리입니다. 물론 드로우콜을 위해서 매우 이상적인 작업물입니다! 훌륭합니다!

그렇지만 라이팅의 측면에서 보면 조금 다릅니다. 라이팅에서 영향을 끼치는 범위는 ‘오브젝트에 얼마나 영향을 끼치느냐’ 인데, 이 오브젝트의 중심축은 먼 쪽 1번 라이트에 근접해 있습니다. 즉 이 오브젝트는 아래에 있는 2번 라이트보다 위에 있는 1번 라이트에 더 영향을 받는다고 생각하고 있는 것입니다.

그런 상황에서 ‘조명 1개에만 영향받아라’ 라고 명령을 내렸으니, 멀리 있는 (사실은 거리보다는 밝기를 인식합니다만, 그냥 넘어가겠습니다. 그 원리까지 설명하면 길어지니…) 2번 라이트의 영향은 상콤하게 무시해 줘 버린 것입니다. 재미있게도 이것은 픽셀라이트를 0 로 해도 마찬가지입니다. 저렴한 버텍스 라이트가 가동되어도 역시 이 라이트는 ‘너무 멀다’ 라고 인식하는 것입니다.

이런 경우 해결책은 없을까요? 물론 있습니다!

그것은 라이트를 어떻게 박을 것이냐를 미리 계획하여 오브젝트를 분리해 버리면 됩니다.
즉 한 오브젝트당 한 라이트를 받으므로, 여기서는 오브젝트를 분리해 버려서 두 개로 만들어 버리면 되는 것입니다.

물론 저 부분에 조명 경계선이 나올 것이 걱정되기도 합니다. 하지만 지금 케이스같은 경우에서는 그런 걱정은 전혀 할 필요 없이 효과가 좋았습니다. 사실 이런 정도로 굉장히 눈에 잘 띄게 영향을 주는 라이트는 보통 1개 정도가 대부분이기 때문에, 라이트의 경계가 끝나는 부분에서 끊어지면 그다지 눈에 안띄게 됩니다.

Conclusion (결론)

일단 실시간 라이트를 유지하면서 퍼포먼스를 떨어뜨리지 않고 작업을 할 수 있는 방법에 대해 연구해 보았습니다.

라이트맵이 물론 퀄리티도 좋고 그림자도 나오지만, 작업량이 만만치 않고 수정하기가 대단히 어려운 단점이 있어서 겁내고 있었습니다만 거기에 대한 대안이 나와서 기쁘게 연구해 보았습니다.

일단 이 방식의 장점은

  • 라이트맵 베이킹에 대한 부담이 줄어든다
  • 옵션에 따라 퀄리티와 퍼포먼스 제어가 용이하다
  • 작업의 수정이 매우 간편하다

그리고 단점도 물론 존재합니다

  • 그림자 안나옴
  • 라이트 정밀도 떨어짐
  • 배경 디자인 할 때 라이트의 영향에 따라 오브젝트를 분리해 줘야 좋은 효과가 나옴. 덕분에 약간의 드로우콜 상승유발.
  • 보통 픽셀라이팅 제한을 1로 해두므로 (2로 할까….) 한 오브젝트에 여러 색의 국지적인 강렬한 효과를 주기에는 무리가 있습니다.

하지만 결론적으로 단점보다는 장점이 매우 커서 말이죠… 사용에서 고려만 잘 한다면 이쪽 장점이 더 클 것으로 보이므로 사용 추천입니다 :)

쉽잖아요.

Hugo로 만듦
JimmyStack 테마 사용 중