역자의 말.
내가 넷이즈 항저우에 입사한 것이 2015년 5월 4일. 발표자는 딱 1년 먼저 입사 한 천조우.
당시 천하 사업부에서 만들고 있던 메시아 엔진을 잠깐 봐 준 적이 있는데 그 당시에는 인터페이스만 있고 버그 투성이었지만 10년이 지난 지금은 멀티플래폼 엔진으로서 넷이즈에서 역할을 어느정도 잘 해 주고 있네요.
개발 리드인 천조우가 직접 개발문서를 구성했을테고 내용을 보면 장르의 특성이나 프러덕트 개발 자체에 대한 이해도가 엄청 높다는 것을 알 수 있죠.
2022년 발표자료임에도 최근 하이브리드 툰 스타일의 핵심을 잘 관통하고 있는 발표로 보입니다.
발표 내용에 보면 중국 메이저 게임사에서는 여전히 하고 있는 포커스 그룹 인터뷰를 여전히 하고 있다는 겁니다. 요즘 한국은 아트 쪽은 이런거 안하는거 같던데 일단 그건 제가 잘 모르겠네요. 넷이즈나 텐센트 바이트덴스는 여전히 포커스 그룹 테스트나 인터뷰를 합니다. 아트 파트는 아트 파트대로 하고 국제화 시대라고 해서 해외 인터뷰 에이전시 까지 사용해서 북미, 아시아 , 중국 , 일본, 유럽 이렇게 나눠서 아트에 대한 인터뷰를 3개월 단위로 하곤 했어요.
아마 한국은 -> .... 모르겠네요.


감사합니다.
여러분, GDC에 오신 것을 환영합니다. 오늘 제가 말씀드릴 주제는 “애니메이션 스타일과 물리 기반 렌더링(PBR) 사이에서 조화를 찾는 방법”입니다.
먼저 저와 제 팀에 대해 간단히 소개하겠습니다.
제 이름은 Shen Zhou이고, 저는 2014년에 NetEase Games에 입사했고 NetEase의 천하 스튜디오에서 테크니컬 리드를 맡았고, 광저우와 상하이 스튜디오에서도 일했습니다.
테크니컬 리드로서 제 주 업무는 게임 엔진과 그래픽스 개발이고, 아티스트와 테크니컬 아티스트와 협업해서 보기 좋은 비주얼과 적절한 퍼포먼스 예산을 동시에 만족하는 게임을 만드는 일을 하고 있습니다.
그동안 여러 개의 온라인 모바일 게임을 개발하고 출시했습니다. 보시다시피 대부분이 만화/애니메이션 스타일의 게임들입니다.

현재 저희는 “Extraordinary Ones: Mirage”라는 게임을 개발 중입니다. 이 게임은 멀티 캐릭터 RPG이고, 기존 온라인 게임 “Extraordinary Ones Mobile”과 같은 IP를 기반으로 하고 있습니다.
여기 보시는 장면은 이 게임의 실시간 렌더링 샷입니다.
이 게임에서 저희는 애니메이션 스타일의 아트와 일정 수준의 포토리얼리즘을 결합한 세계를 만들려고 합니다. 플레이 가능한 캐릭터는 거의 100명에 가까우며, 스테이지(레벨)는 100개 이상입니다.
실내 압축 조명(베이크드 라이트) 환경, 현대 도시,그리고 주야(낮·밤) 조건을 모두 포함하는 야외 환경까지 들어가 있습니다.
이게 오늘 발표 주제로 이어집니다.
게임은 모바일과 PC를 포함한 모든 플랫폼을 타깃으로 하고 있고, NetEase 사내에서 개발한 자체 엔진 “Messiah”로 제작하고 있습니다.
게임이 아직 개발 중이기 때문에, 발표에서 보여드리는 모든 이미지는 최종 퀄리티를 대표하지 않는다는 점을 먼저 말씀드리겠습니다.

발표는 크게 두 부분으로 나뉩니다.
1부에서는 애니메이션(애니메) 아트 스타일에 대한 배경 지식, 대표적인 특징, 전통적인 셀 셰이딩 기법, 그 한계, 그리고 셀 셰이딩과 물리 기반 렌더링을 어떻게 결합할 수 있는지에 대한 몇 가지 해결책을 설명하겠습니다.
2부에서는 저희가 이번 게임에서 목표로 삼은 방향과, 하나의 단일 패스 디퍼드 렌더링 파이프라인 안에서 모든 캐릭터에 애니메의 특징을 유지하면서도 물리 기반의 게임 월드를 구성하는 방법, 특수 조명 및 그림자 기법, 커스터마이즈된 셰이딩 모델, 그리고 캐릭터와 모든 환경을 자연스럽게 통합하기 위해 구축한 인게임 룩데브(LookDev) 파이프라인에 대해 설명하고, 마지막에 정리로 마무리하겠습니다.

자, 먼저 “애니메이션(애니) 아트 스타일이란 무엇인가?” 다른 말로, “어떤 요소가 캐릭터를 애니메이션처럼 느끼게 만드는가?”입니다.
여기 전통적인 2D 애니메이션에서 가져온 클래식한 한 장면이 있습니다. 이 장면에서는 애니메의 여러 특징을 볼 수 있습니다.
캐릭터를 보면, 가장 눈에 띄는 단서는 평평한 얼굴(flat face)과 최소화된 색, 단순한 그림자입니다. 또 다른 단서는 실루엣 라인입니다. 실루엣 라인은 형태와 구조감을 만들어 주는 데 굉장히 중요합니다. 예를 들어, 곡선 하나만으로 캐릭터의 코를 표현할 수 있습니다.
좀 더 자세히 보면, 얼굴이 원근 투영이 아니라 “비원근(non-perspective) 투영”이라는 것도 알 수 있습니다. 즉, 입과 코의 크기와 위치가 실제 3D 기준에서 보면 중심에서 벗어나 있다는 뜻입니다. 예를 들면, 입이 약간 오른쪽으로 치우쳐 있죠.
머리카락을 보면, 링 형태의 비등방성(anisotropic) 스펙큘러 하이라이트가 있습니다. 저희는 이를 “shiny headband(빛나는 머리띠)”라고 부릅니다.
그리고 눈과 눈썹은 머리카락 가닥에 의해 부분적으로 가려질 수 있는데, 애니에서는 머리카락 위로 다시 그려서 뚫고 보이게(see-through hair) 표현합니다.
또, 특히 얼굴 주변의 깨끗한 이미지를 유지하기 위해 대부분의 경우 한 개의 메인 광원만 사용하고, 머리카락이 빛을 가려 만들어지는 그림자는 딱딱한(hard edge) 경계를 갖습니다.
이러한 특징들은 수십 년 동안 애니메이션 제작자들에 의해 쌓여 온 스타일적 관습입니다. 이 관습들이 결합되어 관객들이 익숙해진 “애니메이션 아트 스타일”을 형성하게 됩니다.
이 아트 스타일을 실시간으로 렌더링하기 위해 이미 많은 해결책들이 탐구되었고, 시장에 애니메이션 스타일 게임이 많이 나오면서 이런 기법들은 더 발전해 왔습니다.

저희가 첫 번째 툰 스타일 게임 작업을 시작한 것은 2014년입니다. 초기에는 감을 잡기 위해 먼저 2D 스프라이트를 실험했습니다.
이 방식은 단순하고, 컨셉 아티스트가 100% 통제할 수 있었기 때문입니다. 각 스프라이트 조각(piece)마다 모프 애니메이션을 사용했고, 셰이딩은 아주 단순하게 텍스처를 샘플링한 뒤, 통일된 글로벌 라이팅(환경광)을 얇은 앰비언트 맵으로 블렌딩하는 수준이었습니다.
이 방식은 당시 모바일 디바이스 성능 기준으로도 매우 친화적이라는 장점이 있었습니다.
하지만 최근 몇 년 사이에는, 다른 게임들이 2D 스프라이트에 추가적인 기법들을 사용하기 시작했습니다. 예를 들면, 로컬 라이팅이나 리깅을 추가해서 스프라이트 스택에 더 많은 다양성을 부여하는 방식입니다.

그 후 2015년에는 GDC에서 “Guilty Gear Xrd” 아트 스타일 발표에 영감을 받아 저희 게임에도 셀 셰이딩을 도입하기 시작했습니다.
셀 셰이딩(또는 톤 셰이딩)은 컴퓨터 그래픽스를 손으로 그린 그림처럼 보이게 하기 위해 설계된 비포토리얼리스틱 렌더링 기법입니다.
기본 원리는 직관적입니다. 컬러 그라디언트를 줄여서 베이스 컬러와 그림자 컬러 정도의 단계(step)로 줄이는 것입니다. 이를 위해 보통, 기하 노멀(normal)과 광원 방향의 내적(dot product)을 스텝 함수에 통과시켜 사용합니다. 그리고 나서, 포스트 프로세싱 단계에서 에지 디텍션(edge detection)을 쓰거나 백페이스를 뒤집어서 약간 오프셋을 주는 방법으로 실루엣(outline) 라인을 추가할 수 있습니다.

저희는 이전 게임들에서 실시간 셀 셰이딩을 위해 여러 가지 기술과 트릭들을 시도했습니다. 오른쪽 이미지에 보이는 것들이 그 예시들입니다.
대부분은 캐릭터 렌더링에 집중한 기법입니다. 예를 들면, 각 캐릭터마다 가장 보기 좋은 결과를 얻기 위해 라이팅 상한(upper cap)을 고정하거나,
피부에 대해 밝음–어두움 경계에 작은 그라디언트를 만드는 커스텀 스텝 함수를 사용해서 서브서피스 스캐터링 느낌을 흉내 내기도 했습니다. 또는 멀티 채널 램프 텍스처를 사용해서 아티스트가 더 쉽게 컨트롤 할 수 있게 하고, 버텍스 단계에서 노멀을 조작해서 라이팅을 바꾸거나, 사전 계산된(face mask) 페이셜 섀도우 마스크를 사용해서 대부분의 조명 방향을 미리 처리하기도 했습니다.
HDR 파이프라인에서 색 정밀도를 올리기 위해 특수한 컬러 매핑을 사용하는 등, 다양한 기법을 사용했습니다.
이 모든 기법은 최종 셰이딩 결과를 손으로 그린 애니메 컨셉 아트에 최대한 가깝게 만드는 것을 목표로 합니다.

셀 셰이딩은 특히 캐릭터에 대해 게임을 애니메처럼 보이게 만드는 데 매우 효과적인 기법입니다.
대부분의 2D 애니메이션은 캐릭터에 집중하고 배경/환경은 상대적으로 덜 강조하는 경향이 있습니다.
하지만 “게임”에서는 항상 그런 것이 아닙니다. 저희가 이전에 만들었던 현대 도시 배경의 MMORPG에서는 셀 셰이딩 때문에 환경 디자인이 많이 제한되었고, 결국 플레이어의 탐험 경험(exploration experience)을 떨어뜨리는 결과가 나왔습니다.
또, 셀 셰이딩 프로세스에서는 베이스 컬러를 일일이 손으로 그리는 작업이 매우 중요한데, 이 부분에 명확한 표준이 없다 보니 아티스트마다 결과가 많이 달라졌습니다.
마지막으로, 모바일 디바이스 성능이 계속 좋아지면서 많은 현대적인 렌더링 기법들을 모든 플랫폼에 적용하는 것이 가능해졌는데, 셀 셰이딩 기반 게임에 이런 기법들을 무리 없이 도입하는 것은 생각보다 매우 어려웠습니다.

전통적인 셀 셰이딩과 비교하면 물리 기반 렌더링(PBR)은 몇 가지 제약을 추가로 요구합니다.
PBR은 수학적인 이론과 실제 구현을 모두 포함하는 개념입니다. PBR에서는 머티리얼과 조명을 분리해서 정의합니다. 그래서 어떤 조명 환경에서도 잘 동작하는 에셋을 만들기가 쉽습니다.
또한 현실에 가까운 물리 파라미터를 사용해 매우 다양한 재질을 정량적으로 정의할 수 있습니다.
그리고 가장 중요한 점은, 표준화된 PBR 프로덕션 파이프라인이 게임 업계 전반에 널리 채택되었다는 것입니다. 이렇게 보편적으로 쓰이는 표준이 있다는 의미는, 게임 에셋 제작을 많은 외부 업체(아웃소싱)들에게도 맡길 수 있다는 뜻이고, 이는 대규모 게임 월드를 만드는 데 큰 도움이 됩니다.
그래서 저희는 “애니메의 매력을 유지하면서도 물리 기반 월드를 구축할 수 있는가?”라는 가능성을 탐구하기 시작했습니다.

여기 보시는 것은 현재의 “Extraordinary Ones Mobile”의 컨셉 아트와, 같은 IP를 사용하는 신규 게임의 컨셉 아트를 나란히 비교한 것입니다. 저희가 발견한 것은, 특히 얼굴 주변의 피부, 눈, 머리카락이 “이게 애니메인가?”를 결정짓는 가장 큰 요소라는 점입니다.
예를 들어, 완전히 포토리얼한 머리(모자)를 카툰 몸에 얹으면 굉장히 어색하고 이상해 보이겠지만, 반대로 애니 얼굴에 리얼한 옷과 재질을 입히는 방향은 상대적으로 자연스럽게 느껴진다는 것입니다.
실키한 천, 벨벳, 반투명 재질 같은 리얼한 머티리얼과 옷은 충분히 수용 가능하고, 복잡한 조명과 그림자도, 캐릭터와 조화를 깨지 않는 한도 내에서는 오히려 플러스 요소가 됩니다.
이 의견을 검증하기 위해, 위의 두 컨셉 아트에 대해 “Extraordinary Ones Mobile”의 핵심 유저들을 대상으로 설문을 진행했습니다.
인터뷰에 참여한 모든 유저는 두 그림 속 캐릭터가 현재 게임에서 플레이 중인 “같은 애니메 캐릭터”라고 동의했고, 그중 70% 이상이 오른쪽의 새로운 버전을 더 선호했습니다. 그리고 그들 대부분은 애니메 팬이었습니다.

그래서 저희 게임 그래픽의 목표는 다음과 같습니다.
- 애니메의 룩앤필과 PBR의 장점을 결합한다.
- 모든 종류의 조명 환경에 잘 어울리는 다양한 머티리얼을 구축한다.
- 최신 렌더링 기법을 최대한 활용하되, 그래픽 파이프라인을 유연하게 만들어 저사양 모바일부터 고사양 PC까지 모두 커버한다.
- 가능한 많은 디바이스를 지원하기 위해 오버헤드를 최대한 낮게 유지한다.
이것이 실제 게임에서 저희가 얻은 결과입니다.
보시다시피, 전체 환경은 포토리얼리즘에 가깝게 렌더링되고, 앞에서 언급한 애니메의 대표적인 특징들은
캐릭터에 그대로 남아 있습니다.

요약하자면, 저희 접근 방식은 이렇습니다.
포토리얼리스틱 디퍼드 셰이딩 프레임워크 위에 태양광, 로컬 라이트, 글로벌 일루미네이션, 그림자, 앰비언트 오클루전 등 다양한 요소를 지원하는 그래픽 파이프라인을 구축하고, 캐릭터의 일부(피부, 머리카락, 눈 등)에 대해 특수 셰이딩 모델을 추가하며, 서로 다른 BRDF/BXDF를 통합할 때 에너지 보존 법칙을 최대한 지키도록 설계합니다.
그리고 애니메의 대표적인 특징들을 모방하기 위해 커스텀 렌더링 기법을 구현함으로써 아주 비슷한 룩앤필을 얻었습니다. 또한, 인게임 룩데브 파이프라인을 구축해 캐릭터 및 환경 아티스트가 머티리얼과 텍스처를 직접 점검하면서, 게임 월드에서 가능한 모든 카메라 위치·각도에서 셰이딩 결과가 조화롭게 보이는지 검증할 수 있도록 했습니다.

여기 보이는 것은 모바일 디바이스용 미니멀 G-buffer 레이아웃입니다. 가능한 많은 디바이스에서 호환성과 성능을 확보하기 위해 설계되었습니다. 특히 GLES 환경에서 컬러 어태치먼트 최대 4개만 지원하는 저사양 디바이스를 고려했습니다.
Mali GPU의 성능 가이드라인을 만족시키기 위해 컬러 버퍼를 128비트로 얇게 유지했습니다.
현대 모바일 GPU의 타일 기반 지연(TBDR) 아키텍처 덕분에, 프래그먼트 셰이더는 타일 메모리에서 렌더 타깃 데이터를 읽어와 계산을 수행한 뒤, 조합 결과를 다시 쓸 수 있습니다.
G-buffer 생성, 디퍼드 라이팅, 컴포지션을 단일 렌더 패스 안에 구현했습니다. 이것은 제한된 메모리와 대역폭 환경에서 디퍼드 셰이딩을 구현하는 데 중요할 뿐 아니라, 곧 소개할 커스텀 애니 스타일라이제이션 패스들을 구현하는 데도 매우 중요합니다.

먼저 메인 라이트 소스부터 보겠습니다. 보통 야외에서는 태양/달, 실내에서는 메인 로컬 라이트가 대상입니다.
캐릭터용 다양한 셰이딩 모델(피부, 모발, 눈 등)을 지원하기 위해 저희는 하이브리드 “포워드 + 디퍼드 라이팅” 방식을 사용했습니다. 포워드 부분에서는, G-buffer를 생성하는 동안 먼저 정적인 모델에 대해서는 베이크된 라이트맵을 사용해 간접광을 계산하고, 동적인 모델에 대해서는 라이트 프로브의 SH 계수를 해석해 입사광(incoming lighting) 함수를 얻습니다.
머티리얼의 emission 또한 G-buffer에 함께 기록합니다. 애니메 스타일 셰이딩 모델(피부·머리카락·눈 등)은 G-buffer 생성 시점에 간접광 + 메인 직접광을 함께 셰이딩하고, 그 결과를 역시 G-buffer에 저장합니다. 이 방식은 일반적인 포워드 렌더링 파이프라인에서 하는 것과 거의 같습니다.
동시에 스텐실 값으로 “포워드 셰이딩” 영역을 마킹해서, 디퍼드 단계에서 메인 라이트를 처리할 때 해당 픽셀은 건너뛰도록(mask out) 합니다. 메인 라이트를 미리 계산해 두는 이유는, 애니메 스타일 셰이딩 모델에 필요한 파라미터를 제한된 G-buffer 채널 안에 모두 담을 수 없기 때문입니다.
이 과정은 라이트 패스의 속도 향상에도 도움이 됩니다. 서로 다른 BXDF를 통합할 때 필요한 분기(branch) 수가 줄어들기 때문입니다. 또한 기본적으로 카스케이드 섀도 맵(Cascaded Shadow Map), 이미지 기반 스펙큘러(IBL) 맵, 실시간 반사 맵 등을 샘플링하는데, 이 부분은 다른 많은 게임들과 비슷한 구성입니다.

디퍼드 셰이딩의 큰 장점 중 하나는 많은 수의 동적 조명을 상대적으로 쉽게 처리할 수 있다는 점입니다. 이런 로컬 라이트들은 환경과 캐릭터가 잘 통합되어 보이게 만드는 데 큰 도움이 됩니다.
모든 포인트/스폿/랩 라이트를 한 개의 서브 패스 안에 묶어 두고, 그 중 실제 그림자를 만드는 라이트 수는 디바이스 성능 수준에 따라 제한합니다.
그림자 라이트에 대해서는 섀도 맵을 붙이고, 필요할 때만 업데이트합니다.
그 외의 그림자가 없는 라이트들은 간단한 계산으로 앰비언트 라이트처럼 취급합니다.
A11 이후 애플 디바이스에서는 타일 기반 병렬화를 적극적으로 활용해 프래그먼트 셰이더의 조명 계산 병렬성을 높였습니다.

이제 애니메 캐릭터의 가장 눈에 띄는 특징 중 하나인 “평평한 얼굴(flat face)”을 보겠습니다.
저희는 얼굴 노멀을 두 가지 방법으로 얼굴 정면 방향으로 “Shift”하는 기법을 사용했습니다.
얼마나 강하게 노멀을 밀어줄지에 대한 농도(density)는 텍스처를 통해 제공하여, 아티스트가 얼굴에 걸리는 라이팅을 아주 정밀하게 제어할 수 있습니다. 예를 들어, 볼의 부드러운 에지나, 코·입 주변의 그림자 같은 부분입니다.
버텍스 노멀만으로는 충분하지 않습니다. 스켈레탈 애니메이션에 의해 변경될 수 있고, 보간 후에는 정확도가 떨어질 수 있기 때문입니다.
라이팅 방정식 자체는 그대로 두되, 연산에 사용할 노멀 벡터를 우리가 지정한 “얼굴 정면 노멀”로 바꿉니다. 이렇게 하면 얼굴이 여러 개의 로컬 라이트와 상호작용할 때도 자연스럽게 반응합니다.

또, 호흡 같은 아주 작은 움직임에서 캐릭터 얼굴에 조명이 깜빡거리는(flickering) 현상을 줄이기 위해, GI 부분에서는 낮은 차수의 구면 고조파(SH)를 사용해 샘플링합니다.
정면에서는 평평한 얼굴과 물리 기반 머티리얼이 잘 어울리지만, 특정 조명 각도에서 측면(sid e)으로 보면 얼굴 색이 심하게 오버 익스포즈 되는 문제가 생기기도 합니다.
지정된 노멀(얼굴 정면)로 조명을 계산하는 것은 수학적으로는 맞지만, 옆에서 봤을 때 결과 이미지가 어색하게 보이는 것입니다.

이를 설명하기 위해 몇 가지 다이어그램을 준비했습니다.
일반적인 사람 얼굴의 경우, 빛 반사는 어느 정도 범위를 갖지만, 평면에 가까운 애니메 얼굴은 사실상 한 개의 평면처럼 동작합니다.
저희 해결책은 다음과 같습니다.
로컬 라이트에 대해서는, V·L(뷰와 라이트 벡터의 내적)을 활용한 랩(wrap) 함수로 BXDF를 재조정해
라이트가 얼굴에 미치는 효과를 조절하고, 메인 라이트에 대해서는, 섀도 맵을 사용하는 사전 계산(pre-compute) 패스를 통해 전체적인 커버리지(얼마나 가려지는지)를 통계적으로 계산합니다.
(이 부분은 뒤에서 다시 언급하겠습니다.)

이렇게 하면, 좀 더 자연스러운 결과를 얻을 수 있습니다.

얼굴 이외의 피부 렌더링을 위해서는 조금 다른 셰이딩 모델을 사용합니다.
캐릭터의 피부가 환경의 일부처럼 느껴지게 만들기 위해 라이팅 방정식 자체는 PBR 머티리얼과 동일하게 유지하면서, 색(color)을 의도적으로 조작합니다.

전통적인 셀 셰이딩에서는 아티스트가 그림자 색이나 램프 텍스처를 직접 그려 제공하지만, 저희 방식에서는 이런 색 조작을 하드코딩한 뒤 픽셀 셰이더에서 계산식(formula)으로 구현했습니다.
이 방식이 특히 중요해지는 경우가 멀티 캐릭터 게임입니다. 아티스트마다 손으로 그린 색이 다르기 때문에, 여러 캐릭터를 한 화면에 배치했을 때 색 편차가 매우 커지기 쉽기 때문입니다.
이 셰이딩 모델에서는 밝음에서 어두움으로 넘어가는 부분의 애니메 특유의 “하드 트랜지션”을 유지합니다.
그 위에서, 직접광의 휘도(luminance)에 따라 색조(Hue)를 살짝 이동시키고, 특히 어두운 영역과 에지 주변에서는 직접광·간접광의 채도를 기반으로 채도를 높여줍니다.
이런 색 조작을 통해 구조적인 디테일이 강조되고, 콘트라스트가 더 또렷해집니다.

다음은 그림자 렌더링입니다.
대부분의 셀 셰이딩 게임은 캐릭터에 대해 정교한 그림자 테스트를 하지 않습니다. 보통 잘 설계된 알고리즘으로 일종의 “일반화된 그림자 색“을 계산하는 방식이 많습니다.
하지만 PBR에서는 디테일한 그림자와 앰비언트 오클루전이 굉장히 중요한 요소입니다.
캐릭터의 많은 부분이 실제 재질(PBR)을 쓰고 있기 때문에, 이 두 가지(셀 느낌의 큰 그림자와 PBR의 디테일한 그림자)가 서로 조화를 이루도록 만들어야 합니다.
많은 게임과 마찬가지로 메인 라이트에는 카스케이드 섀도 맵(Cascaded Shadow Map)을 사용합니다.
애니메 스타일 캐릭터는 극단적으로 얼굴 클로즈업을 잡는 샷이 많습니다. 이 경우 얼굴이 화면 전체를 차지하기도 합니다.
이런 샷에서는 얼굴에 생기는 그림자의 퀄리티가 매우 중요합니다. 특히 이마 앞머리(hair fringe)로부터 생기는 셀프 섀도우는 평평한 얼굴 위에서 거의 유일한 기하학적 구조물이기 때문입니다. 그리고 애니메 스타일의 얼굴에는 “딱 떨어지는(hard)” 헤어 섀도우가 필요합니다.



여기 동일한 캐릭터에 대해 라이트 박스(섀도우 범위)를 0.2 ~ 0.8로 바꿔가며 렌더링한 결과를 볼 수 있습니다. 전통적인 오브젝트 단위 섀도 맵(예: 0.8)은 여전히 얼굴 주변에 부드러운 그림자를 만들고, 이것은 저희가 원하는 애니메 스타일과 맞지 않습니다.

더 정확한 클로즈업 섀도우를 얻기 위해 저희는 뷰 적응형 섀도 시스템(view-adaptive shadow system)을 구현했습니다. 이 시스템은 가까운 클로즈업부터 멀티 인물 쇼트까지 다양한 거리에서 작동합니다.
화면 공간에서 여러 개의 피벗 포인트 캡슐을 계산한 뒤, 섀도 맵을 생성할 때의 프러스텀 중심과 크기를 조절해 현재 프레임의 캐릭터를 카메라에 딱 맞게 감싸도록 설정합니다.
이 적응형 알고리즘은 게임 내 거의 모든 샷에서 유효하게 동작하고, 아까 보셨던 0.2 결과가 이런 방식으로 나온 것입니다. 다만 여전히 일부 특수한 샷에서는 수동 조정이 필요합니다. 그래서 아티스트가 타임라인 상에서 원하는 프레임에 맞춰 원클릭으로 섀도 위치를 조정할 수 있도록 툴을 제공했습니다.

컷신에서는 각 샷마다 조명과 그림자를 개별적으로 커스터마이징할 수 있습니다. 다만 시간대 시스템(time-of-day system)을 사용하는 야외 환경에서는 이 방식이 그대로 적용되지는 않습니다.
또한 저희는 얼굴 위의 보기 좋은 셀프 섀도우를 위해 헤어 섀도 프록시 패스(hair shadow proxy pass)를 추가했습니다. 실제 헤어와 동일한 스킨 데이터를 사용하는 단순화된 스케일링 메쉬를 하나 더 만들고, G-buffer와 라이팅 사이 어딘가에서 얼굴 정면 벡터와 메인 라이트 방향을 기준으로 버텍스 위치를 약간 오프셋하여 그립니다. 이때 G-buffer에서 기본 데이터를 가져온 뒤, 간접광 부분만 다시 계산해서 결과를 덮어씁니다. 간접광을 약간 약하게 만들어서, 역광(backlight)에서도 항상 헤어 섀도우 느낌이 남아 있도록 합니다.
이 관점에서 보면 헤어 섀도 프록시는 일종의 섀도 + 앰비언트 오클루전 패스처럼 작동하고, 얼굴에만 적용됩니다. 이는 G-buffer에 저장된 셰이딩 모델 ID를 통해 해당 픽셀이 얼굴인지 여부를 쉽게 판단할 수 있기 때문입니다.

셀프 섀도우 외에도 환경에 의해 생기는 그림자(예: 나무 아래에 있을 때 얼굴 위의 얼룩 그림자)도 게임에 포함하고 싶었습니다. 여기서 문제가 되는 것이 부분적인(partial) 그림자입니다. 예를 들어, 캐릭터가 나무 아래에 서 있으면 얼굴 위에 나뭇잎 그림자가 얼룩처럼 생겨야 합니다. 하지만 이 그림자들이 제멋대로 얹히다 보면 애니메 얼굴이 엉망으로 보이는 문제가 생깁니다.
현재 저희의 해결책은 다음과 같습니다.
우선 프리컴퓨트 패스를 하나 두고, 얼굴들을 일렬로 배치한 렌더 타깃(line-shaped render target)에 “얼굴 전용”으로 렌더링합니다.
각 얼굴에 대해 폴리곤을 하나 만들어 프래그먼트 셰이더에서 섀도 맵들로부터 평균 그림자 값을 구해 픽셀 하나에 저장합니다.
이때, 동적 오브젝트의 셀프 섀도우는 라이트 공간에서 깊이를 조정해서 섀도 맵 비교 시 필터링되도록 처리합니다.
이제 실제 렌더링 시점에 해당 캐릭터의 픽셀을 읽으면 “평평한 얼굴 전체에 고르게 퍼진(flattened) 그림자 값”을 얻을 수 있습니다. 캐릭터당 8 플로트 정도의 데이터를 프리컴퓨트용으로 GPU에 전달합니다.
이 중 하나는 “이 캐릭터가 지난 프레임과 같은 캐릭터인가?”를 나타내는 플래그입니다. 이 정보를 이용해
시간적(temporal) 그림자 전이(transition)를 매끄럽게 만들 수 있고, 이는 게임 내에서 이동하면서 카메라를 돌릴 때 굉장히 유용합니다.

머리카락의 비등방성 스펙큘러 헤어 샤인 역시 애니메의 대표적인 특징입니다. 저희는 이것을 “shiny headband”라고 부릅니다.
머리카락은 클래식한 헤어 셰이딩 모델을 사용해서, 노멀 방향을 기준으로 탱전트(tangent)를 회전시키는 방식으로 처리합니다.
하지만 여러 개의 로컬 라이트가 존재하는 상황에서 전통적인 하프 벡터(half vector) 기반 헤어 스펙큘러를 사용하면, 각 방향별로 샤인이 퍼지면서 현실적으로는 맞을지 몰라도 애니메에서 기대하는 “집중된 빛나는 띠” 느낌이 사라집니다.
그래서 저희는 뷰 방향과 메인 라이트 방향을 보간해서 만든 고정된 벡터(fixed vector)를 사용합니다.
메인 라이트에 대해 계산한 스펙큘러 마스크를 G-buffer에 저장해두고, 이 값을 다른 로컬 라이트들이 참조하도록 하여 GGX를 직접 다시 계산하는 대신 재사용합니다. 이렇게 하면 그림에서 보듯 집중된 애니메 스타일 샤인 스팟을 얻을 수 있습니다.

“머리카락을 뚫고 보이는 눈/눈썹(see-through hair)”도 애니메의 중요한 특징입니다. 눈과 눈썹은 캐릭터의 성격을 전달하는 핵심 요소이기 때문에, 일부 만화가들은 머리카락 위에 다시 그려 넣습니다.
표준적인 투명 표현은 알파 블렌드(Alpha blend)를 사용하는 것인데, 이 방법을 그대로 쓰면 그림자까지 함께 블렌딩되어 머리카락이 지저분해 보이는 문제가 있습니다.
저희는 G-buffer 생성 패스에서 프로그램 가능한 블렌딩을 사용해 이 문제를 해결했습니다.
머리카락은 가장 낮은 드로우 우선순위로 그려서 GPU가 이미 그려진 픽셀의 셰이딩 모델 ID를 가져올 수 있게 하고, 이를 통해 아래에 있는 눈/눈썹 픽셀을 인식해서 다른 비율로 블렌딩을 수행합니다.
프로그램 가능 블렌딩을 지원하지 않는 디바이스에서는 별도의 추가 패스로 나머지 G-buffer를 채우는 폴백을 사용합니다.

디퍼드 렌더링 파이프라인에서는 전통적인 투명 머티리얼이 라이팅 이후에 블렌딩되기 때문에, 불투명 물체와 라이팅 일관성이 맞지 않는 문제가 발생합니다. 왜냐하면 이미 제한된 수의 라이트만 계산된 상태에서 블렌딩이 이루어지기 때문입니다. 이런 머티리얼을 제대로 구현하기 위해, 저희는 셰이딩 모델 ID 안에 삼각형 페이스 정보를 인코딩하고, G-buffer 안에 다양한 디더 패턴을 저장했습니다.
그 후 전용 컨볼루션 블러 패스를 통해 패턴 인식과 다층 컬러 블렌딩을 수행하고, 마지막에 스텐실 마스크를 사용해 결과를 다시 씬에 병합합니다.

깨끗한 외곽선(Outline) 역시 애니메의 중요한 특징 중 하나이고, 포토리얼 렌더링에는 등장하지 않는 요소입니다. 저희는 렌더 타깃 해상도를 고려한 클립 공간 노멀을 이용해 외곽선을 1~2픽셀 정도 얇게 유지하려고 했습니다. 또한 두 번째 세트의 버텍스 노멀 데이터를 버텍스 컬러에 저장해두고, 실루엣 버텍스 셰이더에서 사용합니다. 이 라인들은 일반 렌더 요소처럼 G-buffer에 그려지며, 특정 셰이딩 모델 ID가 할당됩니다.
이렇게 하면 나중에 환경에 따라 외곽선의 색/밝기를 조정할 수 있고, 라이팅과 포스트 프로세스(예: Depth of Field)에서 사용할 선형 텍스처 버퍼도 잘 유지할 수 있습니다.
하지만 이런 라인들은 너무 얇기 때문에 TAA(Temporal Anti-Aliasing) 이후에 아예 사라져 버릴 수 있습니다.
이를 해결하기 위해 속도 버퍼(velocity buffer)에서 움직임이 작은(outline 픽셀) 픽셀에 대해 뷰-프로젝션을 다시 계산하여 정확한 위치를 재구축하는 등의 특수 처리를 했습니다.

애니메 느낌에는 애니메이션도 큰 역할을 합니다.
눈, 코, 입에 대해 비원근(non-perspective) 투영을 사용하는 것은 2D에서의 로컬 특성입니다. 애니메 캐릭터는 보통 눈이 크고 코와 입은 매우 작습니다. 이 때문에, 정면에서는 자연스럽게 보이지만 옆에서 보면 3D 모델이 부자연스러워 보이기도 합니다.
이를 해결하기 위해, 저희는 애니메이션 아티스트가 4~6개의 고정 각도에서 조작한 포즈를 바탕으로 어댑티브 페이셜 모디파이어 시스템을 구축했습니다. 런타임에서 카메라의 피치·요(pitch, yaw)에 따라 이 모디파이어 본의 행렬을 조정해서 원래 애니메이션 데이터와 섞어 줍니다.
런타임 계산을 단순화하기 위해 모든 모디파이어 본은 같은 좌표계에서 세팅되어 있습니다.

저희 게임에는 거의 100명에 가까운 플레이어블 캐릭터와 100개 이상의 레벨이 있기 때문에, 각 캐릭터가 모든 환경에서 조화롭게 잘 어울리는지 확인할 필요가 있습니다.
표준 PBR 외에도 캐릭터에는 많은 커스텀 셰이딩 모델을 사용했습니다. 즉, 체크해야 할 사항이 매우 많다는 뜻입니다. 그래서 저희는 새 캐릭터와 환경 에셋을 검수·승인하기 위한 인게임 검증 파이프라인을 구축했습니다.
캐릭터에 대해서는, 엔진 안에서 사용할 수 있는 룩데브 도구를 제공했고, 환경을 빠르게 전환할 수 있도록 했습니다. 또한 표준 PBR 재질에 대한 참조 구(sphere)와 메탈릭 그라디언트를 보기 좋게 배치해서, 복잡한 조명 조건에서도 커스텀 셰이딩 모델에 문제가 없는지 아티스트가 빠르게 확인할 수 있도록 했습니다.
또한, 특정 환경 내에서 애니메 셰이딩 모델의 일관성을 검사하기 위한 간단한 헬프 모드도 준비했습니다. (비표준 파라미터들은 아티스트마다 다르게 쓸 수 있기 때문에 더 중요합니다.)

환경 디자인 측면에서는, 툴에서 레벨 안에 캐릭터들을 지정된 밀도로 랜덤 배치하는 옵션을 제공합니다.
생성된 메쉬 위에 캐릭터를 잔뜩 올려 놓고, 랜덤 애니메이션을 재생하거나 자동 회전시키면서 환경과의 조화를 확인할 수 있습니다. 큰 레벨에서는 관심 영역(Area of Interest) 안에 캐릭터들을 배치하고, 인게임 카메라가 맵 위를 날아다니면서 해당 영역을 업데이트하는 방식으로 검수합니다.
이것이 저희가 대량의 캐릭터와 다양한 환경 조합에 대해 룩데브를 수행하는 방식입니다.
실시간 툴을 사용해 캐릭터 팀과 환경 팀이 즉각적인 피드백을 받고, 이 피드백을 기반으로 빠르게 반복·다듬기를 할 수 있게 했습니다.

마지막으로, 요약을 보겠습니다. 이번 발표에서는 애니메 아트 스타일의 스타일적 관습, 게임에서 애니메 스타일 비주얼을 구현하기 위한 다양한 접근법, 그리고 “Extraordinary Ones: Mirage”에서 저희가 선택한 방법을 이야기했습니다. 또한, 3D에서 애니메의 특징을 재현하고, 이를 물리 기반 렌더링과 조화롭게 공존시키기 위해 사용한 핵심 기술들을 공유했습니다.
모던 그래픽스 기법을 스타일라이즈드 렌더링에 적용하는 사고 과정은 다른 스타일에도 충분히 응용 가능합니다.

이상입니다. 이 발표가 여러분께 작은 생각거리를 제공했기를 바랍니다. 질문이 있으시면 이메일로 언제든 연락 주십시오.
들어주셔서 감사합니다.
'TECH.ART.FLOW.IO' 카테고리의 다른 글
| [번역]언리얼 엔진 5 카툰 렌더링.앞머리 그림자 구현 방법 (포스트 프로세싱 방식 제외) (0) | 2025.11.16 |
|---|---|
| [번역] Unity URP 아웃라인 원신 중대장의 야혼 아웃라인 효과 모방(에너지 교란 아웃라인) (0) | 2025.11.14 |
| [번역] MatCap 박막 간섭 비눗방울 렌더링 (0) | 2025.11.11 |
| [번역] UE5 Add Custom MeshDrawPass (0) | 2025.11.03 |
| [번역] UE5 시스템 솔루션: 고품질 식생 시스템 (0) | 2025.10.29 |