Normal Map과 디테일 텍스처
탄젠트 스페이스 노말맵의 원리, 노말 블렌딩 기법, 디테일 텍스처링으로 표면 퀄리티를 높입니다.
Normal Map의 원리
지오메트리 없이 표면 디테일을 표현
Normal Map은 텍셀마다 표면의 노말(법선) 방향을 저장하여, 실제 지오메트리를 추가하지 않고도 요철이나 디테일을 표현합니다. UE5는 탄젠트 스페이스(Tangent Space) 노말맵을 기본으로 사용합니다.
// 탄젠트 스페이스 노말맵 인코딩
// 텍스처의 RGB 채널에 노말 벡터 저장
R = Normal.x * 0.5 + 0.5 // 좌우 편향 (-1~1 → 0~1)
G = Normal.y * 0.5 + 0.5 // 상하 편향
B = Normal.z * 0.5 + 0.5 // 표면 방향 (항상 양수)
// 평평한 표면: (0.5, 0.5, 1.0) = 보라/파란색
// 이것이 노말맵이 전체적으로 파란색인 이유
// 디코딩 (셰이더 내부):
Normal.xyz = TextureSample.rgb * 2.0 - 1.0
sRGB = false, Compression = Normalmap. UE5는 BC5 압축을 사용하여 RG 채널만 저장하고 B(Z)는 셰이더에서 복원합니다. 이 방식은 BC1/BC3보다 품질이 높으며, 텍스처 임포트 시 Texture Type을 "Normal Map"으로 지정하면 자동 설정됩니다.
DirectX vs OpenGL 노말맵
| 규약 | G 채널 방향 | 사용 엔진/도구 |
|---|---|---|
| DirectX (Y+) | 위쪽이 녹색 밝음 | UE5, CryEngine, Substance |
| OpenGL (Y-) | 아래쪽이 녹색 밝음 | Unity, Blender, Maya |
OpenGL 규약의 노말맵을 UE5에서 사용하면 빛 반응이 뒤집힙니다. 텍스처 디테일에서 Flip Green Channel을 체크하거나, 머티리얼에서 G 채널을 반전(1-G)하여 보정하세요.
노말 블렌딩 기법
여러 노말맵을 합성하는 방법
디테일을 추가하기 위해 여러 노말맵을 합성해야 할 때, 올바른 블렌딩 방법을 사용해야 결과가 자연스럽습니다.
블렌딩 방법 비교
| 방법 | 품질 | 비용 | 설명 |
|---|---|---|---|
| Linear (잘못된 방법) | 나쁨 | 낮음 | 단순 Lerp - 노말 강도가 약해짐 |
| Whiteout Blending | 좋음 | 중간 | UE5 기본 제공. 대부분의 경우에 적합 |
| UDN Blending | 좋음 | 낮음 | 단순하면서도 합리적인 품질 |
| Reoriented Normal | 최고 | 높음 | 물리적으로 가장 정확 |
// Whiteout Normal Blending (UE5 BlendAngleCorrectedNormals)
float3 WhiteoutBlend(float3 n1, float3 n2)
{
return normalize(
float3(n1.xy + n2.xy, n1.z * n2.z)
);
}
// UE5 머티리얼 에디터에서는
// BlendAngleCorrectedNormals 노드를 사용하면 됩니다
UE5는 BlendAngleCorrectedNormals 머티리얼 함수를 기본 제공합니다. 두 개의 Normal 입력을 받아 Whiteout 방식으로 블렌딩합니다. 커스텀 HLSL 없이도 우클릭 검색으로 바로 사용할 수 있습니다.
디테일 텍스처링
근거리에서의 해상도를 높이는 기법
디테일 텍스처는 기본 텍스처 위에 고주파(미세한) 패턴을 타일링하여 겹치는 기법입니다. 카메라가 가까이 다가갔을 때 텍스처 해상도 부족을 보완합니다.
// 디테일 텍스처 노드 구성
// 1. 기본 텍스처 (UV Tiling x1)
TexCoord [UTiling: 1, VTiling: 1]
→ TextureSample (BaseColor 텍스처)
// 2. 디테일 텍스처 (UV Tiling x8~16)
TexCoord [UTiling: 8, VTiling: 8]
→ TextureSample (디테일 텍스처)
// 3. 합성
// Base Color: 기본 * 디테일 * 2 (Overlay 블렌딩)
// Normal: BlendAngleCorrectedNormals(기본N, 디테일N)
// Roughness: 기본R * 디테일R
거리 기반 페이드
디테일 텍스처는 가까울 때만 필요하므로, 거리에 따라 페이드 아웃하면 원거리에서 모아레 패턴을 방지합니다.
// 거리 기반 디테일 페이드
CameraDepthFade
FadeLength: 1000 // 페이드 거리 (cm)
FadeOffset: 500 // 페이드 시작 거리
→ Output (0~1)
// 디테일 블렌딩에 이 값을 알파로 사용
Lerp
A: 기본 텍스처만
B: 기본 + 디테일
Alpha: CameraDepthFade 결과
FlattenNormal과 노말 강도 조절
노말맵의 세기를 파라미터로 제어
노말맵의 강도를 조절해야 할 때, FlattenNormal 노드 또는 수동 계산을 사용합니다.
// 방법 1: FlattenNormal 노드 사용
FlattenNormal
Normal: TextureSample (노말맵)
Flatness: 0.5 // 0=원본, 1=완전 평탄
// 방법 2: 수동 제어 (더 유연)
float3 normal = TextureSample.rgb;
normal.xy *= Intensity; // 파라미터로 강도 조절
normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));
// z를 재계산하여 단위 벡터 유지
// 방법 3: Lerp로 간단히
Lerp
A: (0, 0, 1) // 평탄 노말
B: TextureSample.rgb // 원본 노말
Alpha: Intensity // 강도 (0~1)
Normal.xyz에 단순히 스칼라를 곱하면 노말 벡터가 정규화되지 않아 라이팅 오류가 발생합니다. 반드시 xy만 스케일하고 z를 재계산하거나, FlattenNormal/Lerp 방식을 사용하세요.
핵심 요약
- Normal Map은 탄젠트 스페이스에서 표면 법선을 저장하여 폴리곤 없이 디테일을 표현합니다. sRGB=false, Compression=Normalmap.
- UE5는 DirectX(Y+) 규약을 사용합니다. OpenGL 노말맵은 G 채널을 반전해야 합니다.
- 노말 블렌딩에는 BlendAngleCorrectedNormals(Whiteout) 노드를 사용합니다. 단순 Lerp는 노말 강도를 약화시킵니다.
- 디테일 텍스처는 높은 UV 타일링으로 근거리 해상도를 보강하며, CameraDepthFade로 거리 기반 페이드를 적용합니다.
- 노말 강도 조절은 FlattenNormal 노드 또는 xy 스케일 + z 재계산 방식을 사용합니다.
도전 과제
배운 내용을 직접 실습해보세요
벽돌 Normal Map을 머티리얼에 연결하고, FlattenNormal 노드로 강도를 0.1~2.0까지 조절하세요. Lit/Unlit 뷰모드를 전환하며 Normal Map의 효과를 시각적으로 확인하세요.
저해상도 타일링 텍스처와 고해상도 디테일 텍스처를 TexCoord 스케일을 다르게 하여 블렌딩하세요. BlendAngleCorrectedNormals 노드로 두 Normal Map을 올바르게 합성하세요.
Height Map을 사용하여 Parallax Occlusion Mapping(POM)을 구현하세요. BumpOffset 노드와 ParallaxOcclusionMapping 커스텀 노드의 품질과 성능 차이를 비교하세요.