TECHARTNOMAD | MAZELINE.TECH

UNREAL ENGINE

[MooaToon] 5-3화. 아웃라인

jplee 2026. 9. 27. 16:15

들어가며

5-1화에서는 SDF 얼굴 그림자를, 5-2화에서는 화면 공간 깊이 테스트 방식의 림라이트를 살펴보았습니다. 이번 마지막 화에서는 아웃라인을 다룹니다.

아웃라인의 출발점은 의외의 사실입니다. 엔진 쪽에는 아웃라인 렌더링 코드가 없습니다. 인버티드 헐과 포스트프로세스 두 계열이 전부 머티리얼로 구현되어 있고, 엔진에는 이를 지원하는 메시 데이터 유틸리티만 존재합니다. 왜 그런 설계가 가능한지, 두 계열이 각각 어떤 데이터와 파라미터로 움직이는지를 확인합니다.

마지막 절에서는 세 표현이 머티리얼과 GBuffer를 거쳐 ToonBxDF()에 수렴하는 데이터 경로를 하나의 표로 연결 추적하며 시리즈를 정리합니다. 구성은 앞의 두 화와 같으며, 파라미터명과 값은 실행 중인 에디터에서 실측한 값이며, 셰이더 코드에는 엔진 소스의 파일명과 행 번호를 병기합니다.

무아툰 엔진 비의존성인 아웃라인 처리

아웃라인에서 먼저 확인해야 할 사실은 엔진 쪽에 해당 코드가 없다는 것입니다. 엔진 소스에서 아웃라인 전용 렌더링 패스를 검색하면 순정 SelectionOutline 외에 Mooa 전용 패스는 나오지 않고, FToonGBufferData에도 아웃라인 관련 슬롯이 없으며, ToonBufferA의 비트 배정 주석에도 아웃라인은 등장하지 않습니다.

/*
 * ToonBufferA (RGBA Float 16)
 * x: SpecularColor.r(8)			SpecularColor.g(8)
 * y: SpecularColor.b(8)			SpecularColorRampUVOffset(8)
 * z: DiffuseColorRampUVOffset(8)	RimLightIntensity(4)		RimLightWidth(4)
 * w: DiffuseColorRampIndex(6)		SpecularColorRampIndex(5)	Stencil(5)
 * 
 * CustomData (GBufferD) (RGBA Float 8)
 * x: MainLightShadowColor.r(8)
 * y: MainLightShadowColor.g(8)
 * z: MainLightShadowColor.b(8)
 * w: ReflectionIntensity(4)	ShadingFeatureID(2)		RayTracingShadowFlag(2)
 *
 * Metallic:	FacialShadowSdfLeft(8)
 * Anisotropy:	FacialShadowSdfRight(8)
 */

이것은 누락이 아니라 설계 판단입니다. 3-2화에서 본 MooaToon의 엔진 수정은 GBuffer 슬롯 확보, 셰이딩 모델 분기, 라이팅 루프 개입처럼 "엔진 없이는 불가능한 것"에 한정되어 있습니다. 아웃라인은 머티리얼과 메시 데이터만으로 구현 가능하므로 엔진을 건드리지 않은 것입니다. SDF 얼굴 그림자와 림라이트가 GBuffer 채널과 라이팅 루프를 필요로 했던 것과 대조되는 위치에 있습니다.

인버티드 헐: M_Outline 계열

이 프로젝트의 기본 아웃라인은 인버티드 헐, 즉 메시를 노멀 방향으로 부풀려 뒤집어 그리는 방식입니다. 4화 2절에서 확인한 실측값을 다시 정리하면 다음과 같습니다.

  • 부모 마스터 머티리얼 M_Outline(/MooaToon/Materials): Opaque, 단면(TwoSided=False), 그리고 셰이딩 모델이 MSM_Toon입니다.
  • MI_UnityChan_Outline: Base Color와 Shadow Color 모두 (0.02, 0.02, 0.02)의 거의 검정, Width Scale 1.0, Specular 0.0. 스위치 Use Vertex Color A as Outline Width, Disable Self Shadow, Disable Cast Shadow On Toon이 켜져 있고, Use Smooth Normal Baked In TexCoord23 값이 1.0입니다.

여기서 주목할 것은 셰이딩 모델이 MSM_Toon이라는 점입니다. 아웃라인 헐 자체가 툰 셰이딩 경로로 렌더링되므로, Disable Self Shadow 같은 툰 전용 스위치가 아웃라인에도 그대로 적용됩니다. 아웃라인을 "엔진 밖의 표현"이라고 했지만, 렌더링 자체는 툰 파이프라인 안에서 일어나는 구조입니다.

스무스 노멀이 필요한 이유는 인버티드 헐의 동작 방식에 있습니다. 헐 확장은 버텍스를 노멀 방향으로 밀어내는 연산인데, 하드 엣지에서는 같은 위치의 버텍스가 면마다 다른 노멀을 가집니다. 이 상태로 밀어내기를 하면 엣지를 따라 헐이 찢어져 아웃라인이 끊깁니다. 이를 막으려면 확장 방향 전용의 스무스 노멀이 필요하고, MooaToon은 이것을 UV2·UV3(TexCoord23)에 베이크해 사용합니다.

  • Use Smooth Normal Baked In TexCoord23 스위치가 이 데이터를 읽는 경로입니다.
  • 폭 제어는 버텍스 컬러 알파입니다. Use Vertex Color A as Outline Width가 켜져 있으므로, 머리칼 끝처럼 가늘게 처리하고 싶은 부위는 버텍스 알파를 낮추는 방식으로 파츠별 폭을 조절합니다.
  • 공식 튜토리얼의 Outer Outline 절도 같은 구조(스무스 노멀 베이크와 버텍스 알파 폭 제어)를 안내하며, Houdini 노드 mooa_bakeSmoothedNormalToUV34와 프리뷰용 mooa_outlinePreview가 Art/Models/hda에 함께 동봉되어 있습니다.
  • MooaToon 문서: Controlling the Shape of Outlines

변종: MI_Outline_VertexColorAlphaClip

/MooaToon/Materials에는 같은 M_Outline을 부모로 하는 변종이 있습니다. 이번 화에서 실측한 내용입니다.

  • MI_Outline_VertexColorAlphaClip: 블렌드 모드가 Masked로 오버라이드되어 있고(Opacity Mask Clip 0.001), 스위치 Opacity From Vertex Color만 켜져 있습니다. Use Vertex Color A as Outline Width와 Use Vertex Color RGB as Outline Color는 꺼져 있습니다.

버텍스 알파가 폭이 아니라 불투명도로 쓰이는 변종입니다. 알파를 그린 부위의 헐을 통째로 잘라내는 용도로 읽힙니다. 아웃라인이 원치 않는 곳에 나타나는 경우 — 예를 들어 피부와 의상이 맞닿는 경계 안쪽 — 를 버텍스 단위로 제거하는 장치로 추정되며, 실제 적용 예는 이 빌드에서 확인하지 못했습니다.

포스트프로세스 아웃라인: M_PP_BlurredOutline 계열

두 번째 계열은 포스트 프로세스 아웃라인입니다. /MooaToon/Materials의 목록을 기준으로 M_PP_BlurredOutline과 그 인스턴스 MI_PP_BlurredOutline, 회색조 변종 MI_PP_BlurredOutline_Gray가 있습니다. MI_PP_BlurredOutline의 실측 파라미터는 다음과 같습니다.

종류 파라미터 값

스칼라 Blur Radius 12.0
스칼라 Blur Step Scale 1.0
스칼라 Gradient Feather 0.12
스칼라 Gradient Offset -0.106
스칼라 Gradient Ramp 1.0
스칼라 Gradient Rotation 0.1192
스칼라 Gradient Scale -1.0
벡터 Blur UV Offset (0.01, 0.01)
벡터 Background Color (1.0, 1.0, 0.349)
벡터 Frontground Color (0.859, 0.282, 0.571)
벡터 Inner Color (0.826, 0.216, 0.216)
벡터 Inner Color 2 (1.0, 1.0, 1.0)
벡터 Gradient Tilling (45.0, 45.0)
텍스처 Outline Gradient Map T_PP_OutlineGradient

인버티드 헐이 메시를 늘려 그리는 방식이라면, 이 계열은 화면에 그리는 방식입니다. 파라미터 이름이 알려주는 구조는 화면 공간 엣지 검출에 블러를 적용하고, 그라디언트 맵으로 선의 안쪽과 바깥쪽에 서로 다른 색을 입히는 방식입니다. 전경·배경·안쪽 색이 각각 지정되어 있어 단색 선이 아니라 채색된 번짐을 만드는 데 쓰입니다. 다만 머티리얼 그래프 내부는 조회 API로 읽을 수 없어, 세부 결선은 미확인 상태입니다.

구분 인버티드 헐(M_Outline 계열) 포스트프로세스(M_PP_BlurredOutline 계열)

그리는 방식 메시를 노멀 방향으로 확장해 뒤집어 그린다 화면에 완성된 이미지 위에 후처리로 그린다
필요한 데이터 스무스 노멀(UV2·UV3) 베이크와 버텍스 알파 씬 컬러·깊이 등 화면 버퍼(그래프 내부는 미확인)
폭·색 제어 Width Scale × 버텍스 알파, Base Color·Shadow Color 전경·배경·안쪽 색 등 머티리얼 파라미터
표현 성격 단색 선 채색된 번짐(소프트 아웃라인)
렌더링 경로 툰 셰이딩 경로(MSM_Toon) 포스트 프로세스 체인

같은 폴더의 M_PP_Debug/MI_PP_Debug는 파라미터 오버라이드가 없는 디버그용 포스트 프로세스 머티리얼입니다. 4화 1절에서 본 BP_MooaLookDevTool의 Enable Post Process Debug View(+Debug PP Material) 프로퍼티와 대응하는 자리입니다.

오버레이 아웃라인: 현재 아웃라인 계열로 통합된 에셋

4화 2절에서 "오버레이 아웃라인"으로 분류해 5-3화에서 다루기로 했던 에셋들은 현재 빌드에서 ObjectRedirector, 즉 에셋 이동 후 남겨진 안내 객체입니다.

  • 이동 대상: M_OverlayOutline → M_Outline, MI_OverlayOutline → MI_Outline(둘 다 /MooaToon/Materials), MI_OverlayOutline_UnityChan → MI_UnityChan_Outline(/Game/MooaToonSamples/Characters/UnityChanSD/Materials)을 가리킵니다. 조회 API로는 이동 대상을 읽을 수 없었지만 리디렉터 파일 자체에 대상 경로가 기록되어 있어, 파일을 직접 열어 확인했습니다.
  • 의미: 오버레이 아웃라인은 별도 계열이 아니라 현재의 아웃라인 계열에 통합되면서 이름이 바뀐 것입니다. 리디렉터가 남아 있는 덕분에 구형 경로를 참조하는 자산도 현재 계열로 투명하게 해석됩니다.
  • 이름의 유래: 5.3 시절 문서는 부모로 MI_OverlayOutline을 사용했고 현재 문서는 MI_Outline을 안내합니다.
  • 지원 인프라: MooaToonScripts의 메시 데이터 유틸리티

엔진에 아웃라인 렌더링 코드는 없지만, 아웃라인이 요구하는 메시 데이터를 다루는 에디터 유틸리티는 MooaToonScripts 플러그인에 있습니다(3-2화 참조).

  • MooaSetMeshData — UV2·UV3, 버텍스 컬러, 탄젠트를 메시에 기록하는 디스패처입니다(헤더 MooaToonEditorBPLibrary.h:104).
    • 실제 기록은 MooaSetSkeletalMeshData/MooaSetStaticMeshData가 담당합니다(.cpp:124-251). 스무스 노멀 베이크 결과를 쓰는 통로입니다.
    	static void MooaSetSkeletalMeshData(USkeletalMesh* InSkeletalMesh, int InLOD, TArray<FVector3f>* InPositions, TArray<uint32>* InVertexIndices, TArray<FVector3f>* InNormals,
    										TArray<FVector3f>* InTangents, TArray<FVector3f>* InBinormals, TArray<FColor>* InColors, TArray<FVector2f>* InUV0s,
    										TArray<FVector2f>* InUV1s, TArray<FVector2f>* InUV2s, TArray<FVector2f>* InUV3s);
    
    	static void MooaSetStaticMeshData(UStaticMesh* InStaticMesh, int InLOD, TArray<FVector3f>* InPositions, TArray<uint32>* InVertexIndices, TArray<FVector3f>* InNormals,
    										TArray<FVector3f>* InTangents, TArray<FVector3f>* InBinormals, TArray<FColor>* InColors, TArray<FVector2f>* InUV0s,
    										TArray<FVector2f>* InUV1s, TArray<FVector2f>* InUV2s, TArray<FVector2f>* InUV3s);
    
    	UFUNCTION(BlueprintCallable, meta = (DisplayName = "Mooa Set Mesh Data", Keywords = "Mooa Set Mesh Data"), Category = "Mooa Toon")
    	static void MooaSetMeshData(UObject* InStaticOrSkeletalMesh, int InLOD, TArray<FVector3f> InPositions, TArray<int> InVertexIndices, TArray<FVector3f> InNormals,
    								TArray<FVector3f> InTangents, TArray<FVector3f> InBinormals, TArray<FColor> InColors, TArray<FVector2f> InUV0s,
    								TArray<FVector2f> InUV1s, TArray<FVector2f> InUV2s, TArray<FVector2f> InUV3s)
    	{
    		auto TempVertexIndices = TArray<uint32>();
    		TempVertexIndices.SetNum(InVertexIndices.Num());
    		for (int i = 0; i < TempVertexIndices.Num(); ++i)
    			TempVertexIndices[i] = InVertexIndices[i];
    		if (InStaticOrSkeletalMesh->GetClass() == USkeletalMesh::StaticClass() || InStaticOrSkeletalMesh->GetClass()->IsChildOf(USkeletalMesh::StaticClass()))
    			MooaSetSkeletalMeshData(Cast<USkeletalMesh>(InStaticOrSkeletalMesh), InLOD, &InPositions, &TempVertexIndices, &InNormals, &InTangents, &InBinormals, &InColors, &InUV0s, &InUV1s, &InUV2s, &InUV3s);
    		else if (InStaticOrSkeletalMesh->GetClass() == UStaticMesh::StaticClass() || InStaticOrSkeletalMesh->GetClass()->IsChildOf(UStaticMesh::StaticClass()))
    			MooaSetStaticMeshData(Cast<UStaticMesh>(InStaticOrSkeletalMesh), InLOD, &InPositions, &TempVertexIndices, &InNormals, &InTangents, &InBinormals, &InColors, &InUV0s, &InUV1s, &InUV2s, &InUV3s);
    		else
    			UE_LOG(LogCore, Error, TEXT("%s is not Static Or Skeletal Mesh"), *InStaticOrSkeletalMesh->GetName());
    	}
    
  • MooaGetMeshData — 같은 데이터의 읽기 디스패처(헤더 :78). 구현은 MooaGetSkeletalMeshData/MooaGetStaticMeshData(.cpp:24-123).
  • MooaGetMeshNormalDiffCurvatures — 노멀 차이 곡률 계산 디스패처(헤더 :130). 구현은 Skeletal/Static 쌍(.cpp:254-377).
  • MooaRecomputeMikkTSpaceTangentBinormal — IMeshUtilities::CalculateMikkTSpaceTangents에 위임하는 MikkTSpace 탄젠트 재계산(:379-385).
  • MooaFindNearestPointsOnDynamicMesh — 다이내릭 메시의 최근접점 탐색(:387-412).

이 함수들의 실제 소비자는 플러그인 콘텐츠의 에디터 유틸리티 블루프린트 EUBP_SmoothNormal입니다.

  • BakeFaceForwardDirection과 BakeSmoothedNormalAndCurvature 두 베이크 함수가 이 유틸리티 함수들과 MooaRecomputeMikkTSpaceTangentBinormal를 호출하는 구조이며, 공식 문서의 Scripted Asset Actions > Mooa Toon 메뉴 항목들이 이 자산에 대응합니다.
  • MooaToonScripts의 C++ 쪽에는 "MooaToon (C++)" 서브메뉴로 "Bake Smooth Normal and Curvature"를 등록하던 코드가 남아 있지만 전량 주석 처리되어 있습니다(MooaToonEditorScripts.cpp:16-66). 실제 코드는 5-1화 '데이터 준비' 절에 첨부되어 있습니다.
  • 에디터 안에서 베이크를 완결하는 설계는 C++에서 블루프린트 유틸리티로 구현을 옮겨 현재도 유지되고 있고, Houdini HDA는 같은 기능의 외부 DCC 경로로 병행 제공되는 구조입니다.

실습. 아웃라인을 변경해 봅니다.

  1. MI_UnityChan_Outline을 복제하고, 복제본의 Base Color를 빨간색으로 바꿉니다. 아웃라인이 그려지는 영역이 시각적으로 구분됩니다. 확인 후 색을 원래 값으로 돌립니다.
  2. Width Scale을 0.5와 2.0으로 바꿔 헐의 두께 변화를 확인합니다.
  3. Use Vertex Color A as Outline Width를 꺼 봅니다. 버텍스 알파로 조절되던 파츠별 폭 차이가 사라지고 균일한 폭이 되는 것을 확인합니다.
  4. BP_MooaLookDevTool 디테일 패널의 Enable Outline을 껐다 켜면서 전체 토글 동작을 확인합니다. 이 BP에는 IsDebuggingOutline 함수와 SetCharacterOutlineMaterialParams(노드 53개)가 있어, 디버그 뷰와 파라미터 일괄 주입이 준비되어 있습니다.
  5. 선택 과제입니다. 포스트 프로세스 볼륨의 블렌더블에 MI_PP_BlurredOutline을 추가해 인버티드 헐과 결과를 비교합니다.

연결 추적: 세 표현이 타는 데이터 경로

표로 정리하기에 앞서, 이 경로들이 최종적으로 수렴하는 지점을 확인합니다. 세 표현의 엔진 측 계산은 전부 ToonBxDF() 한 함수에 모여 있고, 이 함수는 BxDF 스위치에서 SHADINGMODELID_TOON 케이스로 진입합니다(ShadingModels.ush:1103-1107, 모바일 경로 제외). 디퍼드 라이팅 루프가 라이트마다 이 함수를 호출하므로, 지금까지 본 계산은 전부 (픽셀 × 라이트) 단위로 실행됩니다. 함수의 프롤로그가 준비하는 값을 보면 앞의 5-1화·5-2화와의 연결점이 정리됩니다.

FDirectLighting ToonBxDF(FGBufferData GBuffer, half3 N, half3 V, FAreaLight AreaLight, FShadowTerms Shadow)
{
	FMooaToonContext MooaToonContext = GBuffer.MooaToonContext;
	FToonGBufferData ToonGBuffer = GBuffer.MooaToonContext.ToonGBuffer;
	FDirectLighting Lighting = (FDirectLighting)0;
	float3 LightColorAndAttenuation = AreaLight.FalloffColor * MooaToonContext.LightColor * AreaLight.Falloff;
	ColorSaturationPowerAndScale(LightColorAndAttenuation, View.MooaLightSaturationScale);

	const float NoL_Full = dot(N, AreaLight.DiffuseL);
	const float NoL_Half = NoL_Full * 0.5f + 0.5f;
	const float3 H = normalize(V + AreaLight.SpecularL);
	const float3 L_ClipSpace = mul(AreaLight.DiffuseL, (float3x3)View.TranslatedWorldToClip).xyz;
	const float2 L_ViewportSpace = (L_ClipSpace.xy * float2(0.5, -0.5));
	const float2 L_ViewportOffsetBase = L_ViewportSpace * rcp(GBuffer.Depth);
  • LightColorAndAttenuation(281-282행) — FalloffColor·LightColor·Falloff의 곱에 전역 채도 보정(MooaLightSaturationScale)까지 적용한 라이트 색입니다. 디퓨즈·스페큘러·림라이트 전부 이 값을 곱셈으로 공유하므로, 툰 파이프라인의 모든 직접광 표현이 라이트 색을 계승합니다.
  • NoL_Half(284-285행) — dot(N, L) * 0.5 + 0.5. 디퓨즈 램프 U 좌표의 기본값이며, 5-1화의 SDF 그라디언트가 덮어쓰는 ShadowGradient가 이 값에서 파생됩니다.
  • H(286행) — 스페큘러용 하프 벡터인데, 라이트 방향으로 DiffuseL이 아니라 SpecularL을 사용합니다. 엔진은 Rect Light 같은 면광원에서 디퓨즈와 스페큘러의 라이트 방향을 다르게 계산하므로(LTC 계열 근사), 스페큘러에는 전용 방향이 주어집니다.
  • L_ViewportOffsetBase(287-289행) — 라이트 방향을 클립 공간에 투영해 뷰포트 UV로 바꾸고 1/Depth를 곱한 벡터입니다. 5-2화의 림라이트와 4화 5절의 화면 공간 헤어 그림자가 공유하는 탐색 기저 벡터로, 이 한 줄이 화면 공간 계열 표현의 공통 출발점입니다.

합성 순서는 Diffuse(디퓨즈 램프) → Specular(PBR 또는 스페큘러 램프) → Rimlight(Specular에 가산)입니다. Shadow.SurfaceShadow는 디퓨즈만이 아니라 스페큘러와 림라이트에도 일괄로 곱해집니다(ToonShadingModel.ush:368, 374, 378, 390, 396). 툰 파이프라인에서는 그림자 안의 직접광 성분이 전부 소멸하는 셈이며, 5-2화 실습에서 확인한 그림자 속 림 소멸이 이 곱셈에서 나옵니다.

4화 6절에서 확인한 경로 — 인스턴스 → M_ToonLayer → MF_MooaToonBaseInput 인코딩 → MP_MooaEncodedAttribute 핀 → ToonBufferA → ToonBxDF() — 를 기준으로, 세 표현(5-1~5-3화)이 각각 어느 구간에 실리는지를 정리합니다.

표현 머티리얼 측 지정 인코딩 슬롯 GBuffer 채널 엔진 측 계산 전역 제어

SDF 얼굴 그림자 Shadow Map 텍스처·Map Channel·Feature 스위치 MP_MooaEncodedAttribute4.x/y Metallic(좌)·Anisotropy(우) 재사용 ApplyDistanceFieldFacialShadow → ShadowGradient → 램프 U 좌표 PP 라이트 타입별 스위치
림라이트 Rim Light Intensity·Width MP_MooaEncodedAttribute3.z/w ToonBufferA.z에 4비트씩 GetScreenSpaceDepthTestRimlightColor → Lighting.Specular r.Mooa.RimLight.* • PP 강도·채도
아웃라인 M_Outline 계열 파라미터·버텍스 데이터 없음(경로 밖) 없음 없음(머티리얼 구현) BP Enable Outline

이 표가 말해 주는 것은, 같은 "표현 조정"이라도 건드려야 할 계층이 표현마다 다르다는 점입니다. 림라이트의 전역 폭은 CVar 또는 룩뎁 BP에서, 파츠별 켬/끔은 머티리얼 인스턴스에서, SDF 그림자의 형태는 외부 도구로 만드는 텍스처에서, 그림자의 질감은 램프 아틀라스에서, 아웃라인의 파츠별 폭은 DCC 단계의 버텍스 데이터에서 각각 결정됩니다. 3-4화의 "무언가를 수정할 때 어느 단계를 건드리는 작업인지 판단하는 것"이라는 프레임이 세 표현에도 그대로 적용됩니다.

정리하며

5-1화부터 이번 화까지, 4화에서 미뤄 둔 세 가지 표현 — SDF 얼굴 그림자, 림라이트, 아웃라인 — 을 관찰, 실습, 경로 추적의 순서로 다뤘습니다. 세 줄로 정리하면 다음과 같습니다.

  • SDF 얼굴 그림자는 미리 그린 디스턴스필드 텍스처와 라이트 각도의 비교로 동작하며, 결과가 빛의 마스크가 아니라 디퓨즈 램프의 좌표가 되도록 설계되어 있습니다. 데이터 운송에는 툰에서 쓰지 않는 Metallic·Anisotropy 채널이 재활용됩니다.
  • 림라이트는 프레넬이 아니라 화면 공간 깊이 테스트로 실루엣을 찾고, 머티리얼 4비트 파라미터·전역 CVar·포스트 프로세스의 세 계층으로 제어됩니다.
  • 아웃라인에는 엔진 코드가 없습니다. 인버티드 헐(스무스 노멀·버텍스 알파 활용)과 포스트 프로세스 블러 아웃라인 두 계열이 전부 머티리얼로 구현되어 있고, 엔진 쪽에는 이를 지원하는 메시 데이터 유틸리티만 있습니다.

3화의 자산 구조 분석, 4화의 머티리얼 실측, 5-1~5-3화의 표현 계층까지 해서, UnityChan SD를 기준으로 한 MooaToon 해부는 마무리되었습니다. 미확인으로 남는 것은 포스트프로세스 아웃라인 머티리얼의 그래프 내부 하나입니다. 오버레이 아웃라인의 이동 대상과 Face Forward 베이크 경로는 리디렉터 파일과 에디터 유틸리티 블루프린트에서 확인을 마쳤고, 그래프 내부만은 머티리얼을 직접 열어야 닿을 수 있는 항목입니다.