TECHARTNOMAD | MAZELINE.TECH

UNREAL ENGINE

[MooaToon] 3-4화.기능별 지도와 커스터마이징 원칙

jplee 2026. 9. 12. 02:07

들어가며

3-1화에서는 엔진과 프로젝트의 전체 구조를 소개하고, 3-2화와 3-3화에서는 각 영역의 주요 구성 요소를 살펴보았습니다. 이번 글에서는 앞서 확인한 내용을 하나의 구조도로 통합하여 정리합니다. 본문에 제시된 수치와 파일명은 실제 디렉터리를 기준으로 확인한 결과입니다.

이 글은 기능별 관련 위치를 빠르게 확인할 수 있도록 구성했습니다. 특정 기능을 수정하거나 구현 방식을 검토할 때 아래 표에서 해당 경로를 확인한 뒤 관련 폴더와 파일을 살펴보면 됩니다. 이후 내용을 검토하는 과정에서도 참고 자료로 활용할 수 있습니다.

전체 구조 한눈에 보기

MooaToon (루트 — 실제로는 두 폴더를 나란히 두는 구조입니다)
├─ MooaToon-Engine\Engine
│   ├─ Plugins\MooaToonScripts     ← 에디터 도구 상자 (C++, 3-2화)
│   ├─ Plugins\MooaToonThirdparty  ← 번들 서드파티 3개 (KawaiiPhysics·VRM4U·VibeUE)
│   ├─ Shaders                     ← 툰 셰이딩의 심장 (신규 2개 + 훅 9개 파일)
│   ├─ Source                      ← 엔진 본체 수정: "Toon" 셰이딩 모델 등록부 (7화의 무대)
│   ├─ Config                      ← BaseEngine.ini, 번들 플러그인 활성화 두 줄
│   └─ Binaries\Win64              ← 우리가 직접 빌드한 에디터 바이너리
└─ MooaToonProject
    ├─ Plugins\MooaToon            ← 머티리얼 & 램프 (C++ 0줄, 88개 에셋 — 4~6화의 무대)
    ├─ Content\MooaToonSamples     ← 살아있는 교과서 (룩뎁 맵 9개)
    ├─ Content\Global 외           ← 데모·테스트 인프라 (Content 전체 543개 .uasset)
    ├─ Config                      ← 프로젝트 설정 (Mooa 전용 항목 0건)
    └─ Art                         ← 아트 원본과 제작 도구 (337MB, Houdini HDA 10종)

각 폴더의 실측 요약은 이렇습니다.

 

위치  역할  실측
Engine\\Plugins\\MooaToonScripts 메시 데이터 전처리를 위한 에디터 블루프린트 함수 라이브러리 모듈 2개 (런타임은 껍데기, 실체는 에디터 모듈)
Engine\\Plugins\\MooaToonThirdparty 의존성 보관함 KawaiiPhysics·VRM4U·VibeUE 번들 3개
Engine\\Shaders 툰 라이팅의 실제 계산 ToonShadingModel.ush·ToonShadingCommon.ush 신규 추가 + 기존 셰이더 9개에 훅
Engine\\Source 새 셰이딩 모델 MSM_Toon 등록, GBuffer 슬롯 ToonBufferA 추가, 뷰 유니폼 파라미터 약 30개 MooaToon 기준 수정 파일 13곳, 전부 // Mooa 마커로 표시
Engine\\Config 번들 플러그인 기본 활성화 BaseEngine.ini에 두 줄, 나머지 세부값은 코드 안의 r.Mooa.*
Plugins\\MooaToon 순수 콘텐츠 플러그인 (머티리얼·램프·레이어) C++ 0줄, .uasset 88개
Content 샘플과 데모 .uasset 543개 (MooaToonSamples 맵 9개 포함)
Config 프로젝트 설정 ini 4개, MooaToon 전용 설정 0건
Art 원본 아트 + 제작 파이프라인 337MB, Houdini HDA 10종, SDF 섀도우 맵 생성 도구

기능 → 위치 대응표

3화 시리즈의 핵심을 한 장의 표로 압축합니다.

하고 싶은 것  열어봐야 할 곳 연재
캐릭터에 툰 셰이딩 적용 프로젝트 Plugins\\MooaToon\\Materials (M_Toon, MI_Toon 계열) 4화
얼굴 그림자·림라이트·헤어 하이라이트 조절 머티리얼 인스턴스 파라미터 + 포스트프로세스 볼륨의 "Mooa Toon" 카테고리 5화
명암 단수·부드러움 변경 (램프 교체) Plugins\\MooaToon\\Assets의 DiffuseColorRamps·SpecularColorRamps (프리셋 30여 종) 4~5화
아웃라인 방식 변경 Materials의 아웃라인 3계열 (M_Outline, M_OverlayOutline, M_PP_BlurredOutline) 5화
코드 없이 기능 조합·수정 머티리얼 에디터 (머티리얼 레이어 ML_ToonBaseInput와 MLB_ToonBaseBlend) 6화
씬·카메라 단위 분위기 조절 (노출, GI, 그림자 색) 포스트프로세스 볼륨의 "Mooa Toon" 카테고리 (보간 지원) 5화
전역 기본값·디버그 뷰 r.Mooa.* 콘솔 변수 13개 (아래 부록 표) 필요 시
렌더링 방식 자체를 변경 엔진 Source와 Shaders (// Mooa 마커로 검색하면 수정 지점이 전부 나옴) 7화
메시 데이터 전처리 자동화 (노멀 스무딩, 탄젠트 재계산) 엔진 MooaToonScripts와 프로젝트의 EUBP_SmoothNormal 3-2화
얼굴 SDF 그림자 맵 제작 Art\\DistanceFieldFacialShadowSamples (ShadowThresholdMap.exe) 5화
캐릭터 원본 데이터 가공 (Houdini) Art\\Models의 mooa_ 접두사 HDA 10종 3-3화
VRM 캐릭터 임포트 MooaToonThirdparty의 VRM4U 3-1화
머리카락·치마 물리 MooaToonThirdparty의 KawaiiPhysics (샘플: Content\\KawaiiPhysicsSample) 필요 시
샘플 기능의 구현 방식 학습 Content\\MooaToonSamples (맵 9개) 전 화
프로젝트 기본 동작 변경 Config의 ini 4개 필요 시

한 가지 짚고 갈 점이 있습니다. "렌더링 방식 자체를 변경"하는 곳은 이름만 보면 MooaToonScripts처럼 보이지만, 실제로는 엔진 본체인 SourceShaders입니다. MooaToonScripts는 렌더러가 아니라 에셋 제작을 돕는 에디터 도구 상자라는 것이 3-2화의 결론이었죠. 이름이 비슷한 폴더들이 많으니, 표의 경로를 기준으로 삼으세요.

머티리얼 레이어가 낯설다면: 언리얼의 머티리얼 레이어는 포토샵 레이어처럼 머티리얼을 겹쳐서 조합하는 기능입니다. MooaToon은 툰 기본 입력 레이어(ML_ToonBaseInput)와 블렌드 규칙(MLB_ToonBaseBlend) 위에 파츠별 레이어를 얹는 구조로, 6화에서 자세히 다룹니다. 공식 문서는 Material Layers를 참고하세요.

부록: r.Mooa.* 콘솔 변수 13개

SceneRendering.cpp에 정의된 전역 스위치와 기본값입니다.

콘솔 변수  기본값  역할
r.Mooa.DebugValue 0 디버그 뷰 (0이면 비활성)
r.Mooa.AmbientOcclusion.DynamicAOIntensity 0 동적 AO 강도
r.Mooa.DiffuseColorRamp.EnablePostRampShadow 0 켜면 그림자가 디퓨즈 램프 샘플에 영향을 주지 않음
r.Mooa.DiffuseColorRamp.EnablePostRampMaterialAO 0 켜면 머티리얼 AO가 디퓨즈 램프 샘플에 영향을 주지 않음
r.Mooa.DiffuseColorRamp.UVOffsetMaxRange 0.25 디퓨즈 램프 UV 오프셋 최대 범위
r.Mooa.SpecularColorRamp.UVOffsetMaxRange 0.25 스페큘러 램프 UV 오프셋 최대 범위
r.Mooa.RimLight.MaxWidth 1.0 화면 공간 림라이트 최대 폭
r.Mooa.RimLight.DepthTestThreshold 2.0 림라이트 깊이 테스트 임계값
r.Mooa.RimLight.DepthTestFadeDistance 10.0 림라이트 깊이 페이드 거리
r.Mooa.HairShadow.Intensity 1.0 헤어 섀도우 강도
r.Mooa.HairShadow.Width 1.0 헤어 섀도우 폭
r.Mooa.HairShadow.DepthTestThreshold 0.0 헤어 섀도우 깊이 테스트 임계값
r.Mooa.HairShadow.DepthTestFadeDistance 5.0 헤어 섀도우 깊이 페이드 거리

3-1화에서 정리했듯, 씬 단위 조정은 포스트프로세스 볼륨의 "Mooa Toon" 카테고리가 정석 경로입니다. 이 변수들은 그 아래의 전역 스위치이고, 프로젝트별 기본값을 리빌드 없이 바꾸고 싶을 때만 DefaultEngine.ini[ConsoleVariables] 섹션에 덮어쓰면 됩니다.

거꾸로 읽기

이 지도의 사용법을 실제 사례로 한 번 따라가 보겠습니다. "얼굴 그림자가 왜 이렇게 나오지?"라는 의문이 생겼다고 가정합시다.

  1. 증상 재현 (샘플): Content\MooaToonSamples\Maps\L_LookDev_UnityChan.umap을 열고 메인 라이트를 돌려가며 얼굴 그림자를 관찰합니다.
  2. 인스턴스 확인 (프로젝트): 얼굴에 적용된 머티리얼 인스턴스(MI_UnityChan_Face 계열)의 파라미터를 봅니다. 여기 있는 값이 겉모습의 대부분을 결정합니다.
  3. 레이어와 함수 (프로젝트 플러그인): 부모를 따라 올라가면 머티리얼 레이어 ML_ToonBaseInput과 머티리얼 함수 MF_MooaToonBaseInput, 그리고 MF_MooaEncodeAttributes에 도달합니다.
  4. 연결부 (엔진↔프로젝트): 이 함수가 채우는 값은 엔진의 머티리얼 입력 핀 MP_MooaEncodedAttribute0~4와 이름 그대로 맞물립니다. 3-3화에서 말한 "약속된 규격"이 바로 이 지점입니다.
  5. 계산 (엔진): 최종 계산은 Engine\Shaders\ToonShadingModel.ush의 Distance Field Facial Shadow 코드에서 일어납니다. 좌/우 SDF 텍스처를 라이트 각도에 따라 블렌드하는 방식입니다.
  6. 원천 (아트 파이프라인): 그 SDF 텍스처를 만드는 도구는 Art\DistanceFieldFacialShadowSamples에 있습니다. 각도별 얼굴 그림자 마스크 5장을 sdf_shadow_threshold_map의 실행 파일에 넣어 보간 맵을 굽습니다.

한 줄로 정리하면: 증상(샘플 맵) → 인스턴스 → 레이어/함수 → 엔진 셰이더 → 아트 도구. 이 체인은 두 세계와 Art까지 세 영역을 전부 가로지릅니다. 지도가 있으면 이 체인의 어느 마디로든 바로 점프할 수 있습니다.

구조에서 도출되는 세 가지 원칙

앞서 정리한 구조와 실측 결과를 바탕으로, MooaToon을 수정하거나 분석할 때 적용할 수 있는 세 가지 원칙을 정리합니다.

원칙 1: 프로젝트 영역을 우선 확인한다.

명암 조정, 하이라이트 설정, 머티리얼 조합 등 일반적인 커스터마이징은 대부분 프로젝트 플러그인에서 처리할 수 있습니다. 따라서 문제가 발생하거나 표현을 변경해야 할 경우에는 엔진 코드를 수정하기 전에 머티리얼과 관련 에셋만으로 해결할 수 있는지 먼저 검토하는 것이 적절합니다.

이 원칙은 프로젝트 플러그인의 구성에서도 확인할 수 있습니다. Plugins\\MooaToon은 C++ 코드가 포함되지 않은 순수 콘텐츠 플러그인으로, 총 88개의 에셋을 제공합니다. 또한 디퓨즈 램프 18종, 스페큘러 램프 14종, 보조 커브 6종의 프리셋과 {Opaque, TwoSide, Translucent} × {일반, VRM} 조합의 머티리얼 인스턴스 구조를 갖추고 있습니다. 이는 주요 표현 요소를 프로젝트 영역에서 조정할 수 있도록 설계되었음을 의미합니다.

원칙 2: C++ 수정은 필요한 경우에만 수행한다.

엔진 영역의 수정은 렌더링 파이프라인 자체의 동작을 변경해야 할 때 고려해야 합니다. MooaToon은 일반적인 표현 수정이 머티리얼 에디터에서 가능하도록 주요 기능을 외부 파라미터와 에셋으로 제공하고 있습니다.

엔진 수정의 범위는 MooaToon의 구현 구조에서 확인할 수 있습니다. 하나의 셰이딩 모델("Toon")을 추가하기 위해 enum 등록(EngineTypes.h), 머티리얼 프로퍼티(MP_MooaEncodedAttribute0~4), HLSL 트랜슬레이터, GBuffer 슬롯(ToonBufferA), 베이스 패스 인코딩, 디퍼드 라이팅 디코딩, 레이트레이싱 페이로드 등 일곱 개 계층을 수정해야 합니다. MooaToon은 이러한 엔진 수준의 구현을 사전에 완료하고, 그 결과를 머티리얼 입력 핀과 램프 형태로 제공합니다. 따라서 대부분의 활용 사례에서는 C++ 수정이 필요하지 않습니다.

원칙 3: 샘플을 구현 참고 자료로 활용한다.

기능의 동작과 구현 방식을 확인할 때는 MooaToonSamples를 우선적으로 검토하는 것이 효율적입니다. 샘플 레벨에서 결과를 확인한 뒤 적용된 머티리얼과 관련 함수를 순차적으로 추적하면 각 기능의 처리 구조를 파악할 수 있습니다. 이와 같은 역추적 방식은 본 시리즈에서 사용하는 기본 분석 절차입니다.

해당 폴더에는 메인 L_LookDev, 라이팅 서브레벨, UnityChan SD·GIFirst·Pose, VRM, 시간대 데모 L_TimeOfDay, 볼류메트릭 페인팅 등 9개의 룩뎁 맵이 포함되어 있습니다. 또한 룩뎁 도구 BP_MooaLookDevTool과 비교용 머티리얼 인스턴스 MI_NPR·MI_PBR도 제공됩니다. 따라서 특정 기능을 검토할 때 관련 샘플 맵을 확인하면 구현 결과와 설정 방식을 함께 파악할 수 있습니다.

정리하며

3화 시리즈를 통해 우리는 수만 개의 파일을 두 세계와 아홉 개의 핵심 폴더로 압축했습니다(엔진 쪽 다섯, 프로젝트 쪽 넷). 이제 폴더 트리를 봐도 현기증 대신 방향감각이 먼저 오실 겁니다.

구조를 아는 사람만이 두려움 없이 코드를 고칠 수 있습니다. 그리고 그 구조는 이제 여러분 것입니다.

다음 4화부터는 드디어 실전입니다. 프로젝트 플러그인 Plugins\MooaToon의 머티리얼 레이어를 열어서, 캐릭터에 일본 애니메이션풍 툰 셰이딩을 직접 입혀보겠습니다.