Published on

3D를 2D 웹툰처럼: 포스트 프로세스로 빚어낸 카툰 셰이딩과 아웃라인 구축기

Authors
  • avatar
    Name
    Nori
    Twitter
    3D Artist

최근 웹툰 독자들의 눈높이가 높아지면서 배경에 요구되는 스케일과 연출의 밀도 또한 몰라보게 정교해졌습니다. 끝없이 펼쳐진 대제국의 수도, 복잡한 사이버펑크 도시, 혹은 안개가 자욱한 웅장한 대자연까지.
기존의 가벼운 3D 툴만으로는 쏟아지는 폴리곤 데이터와 고난도 라이팅 퀄리티를 감당하기에 분명한 한계가 있었습니다.

우리는 이 지점에서 Unreal Engine을 웹툰 파이프라인의 핵심으로 도입하기로 결정했습니다.
엔진 안에서 거대한 세계관을 자유롭게 구축하면서, 동시에 웹툰 특유의 친숙한 룩까지 한 번에 완성하겠다는 도전이었습니다.
처음 세팅된 언리얼 배경 위에 작가님의 2D 캐릭터 작화를 얹었던 순간을 지금도 잊지 못합니다. 엔진이 만들어내는 풍부한 간접광과 사실적인 질감은 그 자체로 훌륭했습니다. 하지만 선과 면으로 축약된 2D 캐릭터가 그 위에 서는 순간, 마치 실사 사진 위에 오려 붙인 스티커처럼 지독한 이질감이 느껴졌습니다.

이 간극을 메우기 위해 우리는 렌더링의 최종 단계인 포스트 프로세스(Post Process)를 활용해 사실적인 빛을 2D의 면으로 눌러 카툰 셰이딩을 구현하고, 그 위에 사람 냄새나는 펜 터치를 직접 그어내는 방식을 고안했습니다.
이 글은 3D 배경과 2D 캐릭터 사이의 아득한 이질감을 메우기 위해 분투한 우리 팀의 웹툰 룩뎁(LookDev) 여정입니다. 엔진이 가진 기계적인 완벽함을 일부러 뭉개고 타협하면서, 만화 원고라는 하나의 캔버스 안에서 조화를 찾고자 했던 치열한 고민을 여러분과 공유하려 합니다.

왜 머티리얼이 아닌 포스트 프로세스인가?

보통 카툰 렌더링이라고 하면 개별 오브젝트의 재질(Material)을 수정하는 방식을 먼저 떠올립니다.
하지만 주간 연재라는 극한의 일정 속에서 매주 새로운 배경을 만들어야 하는 아티스트들에게 효율성은 생존 문제입니다.

외부 마켓플레이스 에셋이나 과거에 만든 프랍을 가져올 때마다 수많은 머티리얼을 일일이 뜯어고쳐야 한다면 어떨까요? 이는 곧 파이프라인의 치명적인 병목이자 끔찍한 유지보수 지옥을 의미합니다.
그래서 우리는 아티스트가 평소처럼 자유롭게 배경을 세팅하면, 카메라 필터가 화면 전체를 일괄적으로 웹툰화하는 '통합 처리 방식'을 택했습니다.
덕분에 작업의 자유도는 보존하면서 시각적 통일성은 한 번에 확보할 수 있었습니다.

Step 1. 면을 칠하다

3D 모델링이 실사처럼 보이는 이유는 표면에 맺히는 부드러운 빛의 흐름 때문입니다. 우리는 이 복잡한 연산을 강제로 평면화했습니다. 엔진이 렌더링한 최종 이미지 (PostProcessInput0)에서 사물의 고유 색상(Base Color) 데이터를 나누어 순수한 '흑백 라이팅 마스크'만 추출했습니다.

이 마스크를 기준(Alpha)으로 삼아, 원본 Base Color와 어둡힌 Base Color를 Lerp(보간) 노드로 섞어주는 방식을 택했습니다. 수십 단계로 이어지던 빛의 그라데이션 대신, 빛을 받는 면과 그림자가 지는 면으로 압축하여 카툰 특유의 플랫한 룩을 완성한 것입니다.

여기서 특히 신경 쓴 것은 분위기를 다루는 유연함이었습니다. 명암 임계값(Threshold)의 위치와 콘트라스트를 조정할 수 있는 슬라이더를 심어 경계를 정밀하게 제어할 수 있게 만들었습니다.
또한 명부와 암부의 틴트(Tint) 색상을 변경 가능하게 해 아티스트가 장르 분위기에 맞춰 별도의 조명 수정 없이 자유롭게 조절하게 했습니다.

아래 툰셰이더 적용 전, 적용 후, Tint 값 조절 후의 비교 이미지입니다.

Cinematic.png Cinematic (셰이더 적용 전)
셰이더 적용 후.png 셰이더 적용 후
Tint 값 조정.png Tint 값 조정

이때 가장 큰 난관은 언리얼의 핵심 기술인 루멘(Lumen)과의 충돌이었습니다.
루멘은 공간에 빛이 어떻게 퍼지는지 계산하는 실시간 ‘전역 조명(GI)’과 표면에 무엇이 비치는지를 다루는 ‘반사(Reflection)’를 하나로 통합한 언리얼 5의 기술입니다.
실사 렌더링에서는 그 자체로 훌륭했지만, 안타깝게도 우리의 카툰 렌더링 파이프라인과는 맞지 않았습니다. 실시간으로 계산되는 빛의 데이터들이 깔끔한 면 위에서는 지저분한 노이즈로 변질되었기 때문입니다. 결국 우리는 공간의 빛을 계산하는 루멘을 완전히 끄는 결단을 내렸습니다.

하지만 역시나 루멘을 끄니 또 다른 문제가 생겼습니다. 화면이 깔끔해진 것은 좋았지만, 반사 위주의 실외 건물들이 환경의 빛을 전혀 받지 못해 심한 단절감이 느껴졌습니다. 2D 특유의 플랫함은 유지하면서도, 사물이 공간 속에 자연스럽게 놓여 있다는 느낌을 줄 방법이 필요했습니다.

그래서 우리는 진짜 빛을 계산하는 대신, 가짜 반사광(Reflection) 정보를 활용해 간접 조명 효과를 흉내 내기로 했습니다. 이 가짜 반사광은 카메라 시점 기반의 벡터 연산을 활용했습니다.
Camera Vector나 Reflection Vector처럼 카메라가 표면을 바라보는 각도에 실시간으로 반응하는 노드에 환경 맵(HDRI)의 색상과 밝기 정보를 샘플링한 뒤, 그 결과값을 머티리얼의 Emissive Color에 직접 연결했습니다. 이렇게 노드를 구성하면 실시간 빛 연산 없이도, 씬 내부의 오브젝트들이 주변 환경의 반사를 부드럽게 받고 있는 것처럼 보이게 됐습니다.
원본 이미지를 살짝 섞어주어, 2D 특유의 플랫함을 유지하면서도 발광체 디테일이 살아남는 최적의 타협점을 찾았습니다.

아래 비교 이미지에서 벡터를 활용한 Reflection 구현 전후 차이를 확인하실 수 있습니다.

Before Reflection.png Reflection 적용 전
After Reflection.png Reflection 적용 후 (하늘과 건물 반사 적용된 모습)

하지만 이러한 방식에도 한계는 존재했습니다.
화면의 근간이 되는 것이 결국 텍스쳐 맵이 주 재료인 Base Color 이다 보니, 원본 알베도(Albedo) 텍스쳐 자체가 실사 기반의 텍스처일 경우 실사 디테일이 그대로 남아 카툰의 깔끔한 면을 해치곤 했습니다.
이를 근본적으로 해결하기 위해, Base Color 자체에도 포스터 라이제이션(Stepping) 연산을 적용해 명암을 단순화하거나, 명암 이외 텍스처 자체의 묘사 밀도를 압축하는 방식을 테스트 중 입니다.

Step 2. 선을 긋다

면을 정리했다면, 이제 선을 구현할 차례입니다. 웹툰에서 선은 형태를 구성하는 용도를 넘어, 작가의 2D 캐릭터와 3D 배경을 하나의 원고처럼 묶어주는 핵심 연결 고리입니다.

외곽선을 추출하기 위해 우리는 깊이(Depth) 버퍼를 활용해 인접 픽셀 간의 깊이 차이가 큰 경계에 선을 그리는 방식을 사용했습니다. 보통은 부드러운 선을 얻기 위해 8방향을 훑는 필터를 쓰지만, 우리는 상하좌우 4방향만 탐색하는 방식을 택했습니다. 특유의 거칠고 각진 느낌이 작가가 펜으로 쓱쓱 그은 듯한 날렵한 선 질감과 훨씬 잘 어울렸기 때문입니다.

또한, 사람의 펜 터치와 같은 효과를 위해 2D적인 원근법에 접근했습니다. 실제 손 그림은 멀리 있는 사물을 그릴 때 묘사를 생략하고 펜에 힘을 빼며 연하게 그리곤 합니다. 우리는 이를 수학적인 수치로 구현해, 카메라와 거리가 멀어질수록 선의 굵기가 자연스럽게 얇아지도록 설계했습니다.

Depth Outline.png Depth Outline

또한, 외곽 실루엣 뿐만 아니라 물체 내부의 미세한 디테일을 잡기 위해 픽셀의 각도 차이(World Normal) 데이터도 함께 활용했습니다. 표면의 법선 벡터가 꺾이는 지점을 선으로 표현하는 방식입니다. 이는 천의 주름이나 나무결 같은 부드러운 내부 묘사할 때 유용합니다.

실제 웹툰 작가들의 원고를 보면 상황에 따라 선을 쓰는 방식이 다릅니다. 먹선(Black)으로 형태를 강하게 잡기도 하지만, 주변 색상에 맞춰 자연스럽게 스며드는 '색깔 있는 선(Colored Line)'을 혼용해서 쓰곤 합니다. 우리는 노말로 추출된 내부 외곽선에 오브젝트의 본래 색상(Base Color)을 조절해 섞을 수 있는 파라미터를 추가했습니다. 그 결과, 상황에 맞는 유연한 라인 연출이 가능해졌습니다.

Colored Normal Line.png Colored Normal Line 구현 모습

하지만 뎁스와 노말 기반의 두 아웃라이너를 함께 사용하자 문제가 생겼습니다. 건물의 바깥 테두리처럼 거리 차이와 각도 차이가 동시에 크게 발생하는 곳에서 두 셰이더가 선을 중복으로 그어버린 것입니다. 선 굵기가 통제되지 않고 지저분하게 뭉개지는 이 현상을 해결하기 위해, 우리는 IF 노드를 활용해 겹침 방지(Culling) 로직을 설계했습니다.

먼저 계산된 노멀 엣지(Normal Edge)를 0~1 사이로 정규화 했습니다. 값이 0에 가까울수록 표면이 완만하게 이어지는 내부 디테일이고, 1에 가까울수록 급격하게 꺾이는 강한 경계선을 의미합니다. 이 데이터를 바탕으로 IF 노드의 조건을 다음과 같이 설정했습니다.

IF Node 설정

IF Node.png
  • A: 계산된 Normal Edge 값
  • B: 0.4
  • A > B : 0
  • A < B : A값 (기존 유지)

이 수식의 의미는 간단합니다. 엣지 값이 0.4 이상이라는 것은 4방향의 표면 방향이 서로 꽤 강하게 어긋나며 꺾였다는 뜻입니다. 이런 강한 모서리는 이미 뎁스(Depth) 셰이더가 두꺼운 외곽선으로 그렸을 확률이 상당히 높습니다. 따라서 임계값(0.4)을 넘는 데이터는 과감히 지워버리고, 그 이하의 자잘한 데이터만 유지하는 구조입니다. (물론 이 B 값은 아티스트가 씬에 맞춰 미세 조정할 수 있도록 파라미터화했습니다.)

이 직관적인 겹침 방지 로직 덕분에 뭉개지던 두꺼운 중복 선은 말끔히 사라지고, 꼭 필요한 섬세한 내부 주름만 화면에 예쁘게 남길 수 있었습니다.

IFBefore.png IF노드 적용 전
IFAfter.png IF노드 적용 후
아웃라인 적용 전.png 아웃라인 적용 전 (Step 1)
아웃라인 적용 후.png 아웃라인 적용 후 (Step 1 + Step 2)

본 글에서 설명한 아웃라인 셰이더 로직은 아래 깃허브(GitHub) 저장소를 통해 확인하실 수 있습니다. 더 나은 구현 방식이나 개선 아이디어가 있다면 언제든 피드백과 공유 부탁드립니다.
GitHub - Realdraw_Outline

마치며

이번 룩뎁(LookDev) 파이프라인 구축은 단순히 기술적인 퀘스트를 넘어, 3D 아티스트로서 가졌던 '사실적이고 완벽한 렌더링'에 대한 강박을 내려놓는 과정이었습니다.

웹툰 배경에 있어 훌륭한 기술이란 현실과 얼마나 똑같은지를 증명하는 것이 아니라, 작가의 2D 원고 안에서 얼마나 위화감 없이 숨 쉴 수 있는지에 달려있다는 것을 뼈저리게 깨달았습니다. 엔진의 기계적인 완벽함을 일부러 뭉개고, 2D 작가의 거칠지만 따뜻한 손맛을 셰이더로 구현해 냈을 때 비로소 3D 배경이 만화 원고로서의 생명력을 얻는 것을 팀 전체가 체감할 수 있었습니다.

우리의 궁극적인 목표는 독자들이 웹툰을 스크롤할 때, "아, 이건 3D 배경이구나"라고 인식조차 하지 못할 만큼 3D와 2D 작화의 경계를 허무는 것입니다. 작가님의 펜 끝에서 탄생한 캐릭터가 언리얼이 빚어낸 공간을 이질감 없이 디딜 수 있도록, 웹툰 원고에 온전히 스며드는 룩을 향한 우리 팀의 치열한 고민과 시도들을 앞으로도 계속 공유하겠습니다.

긴 글 읽어주셔서 감사합니다.