들어가며
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처럼 보이지만, 실제로는 엔진 본체인 Source와 Shaders입니다. 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] 섹션에 덮어쓰면 됩니다.
거꾸로 읽기
이 지도의 사용법을 실제 사례로 한 번 따라가 보겠습니다. "얼굴 그림자가 왜 이렇게 나오지?"라는 의문이 생겼다고 가정합시다.
- 증상 재현 (샘플):
Content\MooaToonSamples\Maps\L_LookDev_UnityChan.umap을 열고 메인 라이트를 돌려가며 얼굴 그림자를 관찰합니다. - 인스턴스 확인 (프로젝트): 얼굴에 적용된 머티리얼 인스턴스(
MI_UnityChan_Face계열)의 파라미터를 봅니다. 여기 있는 값이 겉모습의 대부분을 결정합니다. - 레이어와 함수 (프로젝트 플러그인): 부모를 따라 올라가면 머티리얼 레이어
ML_ToonBaseInput과 머티리얼 함수MF_MooaToonBaseInput, 그리고MF_MooaEncodeAttributes에 도달합니다. - 연결부 (엔진↔프로젝트): 이 함수가 채우는 값은 엔진의 머티리얼 입력 핀
MP_MooaEncodedAttribute0~4와 이름 그대로 맞물립니다. 3-3화에서 말한 "약속된 규격"이 바로 이 지점입니다. - 계산 (엔진): 최종 계산은
Engine\Shaders\ToonShadingModel.ush의 Distance Field Facial Shadow 코드에서 일어납니다. 좌/우 SDF 텍스처를 라이트 각도에 따라 블렌드하는 방식입니다. - 원천 (아트 파이프라인): 그 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의 머티리얼 레이어를 열어서, 캐릭터에 일본 애니메이션풍 툰 셰이딩을 직접 입혀보겠습니다.
'UNREAL ENGINE' 카테고리의 다른 글
| [MooaToon] 4화 . L_LookDev_UnityChan: UnityChan SD 툰 머티리얼 설정 분석 (0) | 2026.09.21 |
|---|---|
| [MooaToon] 3-3화 . 프로젝트 쪽 해부: 머티리얼 시스템 (2) | 2026.09.10 |
| [MooaToon] 3-2화 엔진 쪽 해부: MooaToonScripts 플러그인 (0) | 2026.09.05 |
| [MooaToon] 3-1화 . 큰 그림: 두 개의 세계 (1) | 2026.09.04 |
| [MooaToon] 2화 . 설치와 빌드: 소스코드에서 나만의 툰 엔진 만들기 (0) | 2026.09.03 |