
## 텍스처 타일링 아티팩트 제거 기법
텍스처 타일링 아티팩트는 지형 셰이더에서 재질이 반복되어 부자연스럽게 보이는 문제를 말합니다. 이를 해결하기 위한 다양한 기법이 있으며, 셰이더 비용 증가를 감수해야 할 수도 있습니다.
### 1. 비-셰이더 기법 (Shader Cost 없음)
* **넓은 영역 피하기:** 동일한 재질이 장거리에서 반복되는 넓은 영역은 피합니다.
* **레이어 블렌딩 활용:** 각 레이어가 다른 타일링 속도를 가지도록 하여 레이어 자체 블렌딩으로 타일링을 분산시킵니다.
* **다른 재질 페인팅:** 타일링이 발생하는 영역에 다른 재질의 일부를 칠해 시각적으로 분산시킵니다.
* **환경 요소 활용:** 지형을 수풀, 나무 등으로 덮어 타일링 아티팩트를 숨깁니다. (장식 요소가 충분히 복잡할 경우 셰이더로 타일링 분산을 하지 않아도 됩니다.)
### 2. 셰이더 기법 (Rotation Layer)
이 기법은 텍스처를 90도 회전시켜 원본 텍스처와 블렌딩하여 타일링을 분산시킵니다.
#### 2.1. 기법 원리
* **텍스처 두 번 샘플링:** 동일한 텍스처를 두 번 샘플링합니다.
* **원본 샘플:** 일반적인 UV 좌표를 사용합니다.
* **회전 샘플:** UV 좌표의 X와 Y를 바꿔 90도 회전시킵니다. (Swizzle 노드 활용)
* **마스크를 이용한 블렌딩:**
* 마스크 텍스처를 준비합니다. (예: Red, Green, Blue 채널별로 다른 크기의 마스크)
* 마스크 텍스처의 특정 채널(예: Blue 채널)을 사용하여 원본 샘플과 회전 샘플을 블렌딩합니다.
* 마스크 스케일 멀티플라이어를 조절하여 마스크의 반복 빈도를 조절합니다.
* **UV 좌표 스케일링:**
* 절대 월드 위치를 스케일링하여 UV 좌표를 생성합니다.
* 이 UV 좌표를 마스크 스케일 멀티플라이어로 나누어 마스크 스케일과 UV 스케일의 비율을 유지합니다.
#### 2.2. 구현 세부 사항 (Unreal Engine 기준)
* **Rotation Layer Material Function 생성:**
* 기존 Simple Layer Material Function을 복사하여 "Rotation Layer"로 이름 변경 후 수정합니다.
* 텍스처 샘플링을 두 번 수행하고, 두 번째 샘플에는 Swizzle 노드를 사용하여 UV 좌표를 YX로 변경합니다.
* Lerp 노드를 사용하여 두 텍스처 샘플을 블렌딩합니다.
* 마스크 텍스처를 위한 Texture Sample과 Texture Input 2D를 추가합니다.
* 마스크 스케일 멀티플라이어를 위한 Input Scale을 추가하고, UV 좌표를 나누는 연산을 수행합니다.
* **정상 맵(Normal Map) 처리:**
* 정상 맵을 회전시킬 때는 Swizzle 노드를 사용하여 Red와 Green 채널을 YX로 바꿔줍니다. (정상 맵은 RGB 순서가 중요하므로 YXZW 순서로 재배열)
* **마스크 텍스처 활용:**
* Blend Mask Texture Input을 생성하고, 기본값으로 Mask 텍스처를 설정합니다.
* 마스크 텍스처의 특정 채널(예: Blue)을 추출하여 Lerp 노드의 Alpha 값으로 사용합니다.
* **마스크 스케일 멀티플라이어:**
* Blend Mask Scale Multiplier float 값을 추가하고, 기본값 1로 시작하여 조절합니다. (예: 15.97)
* UV 좌표를 이 값으로 나누어 마스크의 크기를 조절합니다.
* **최종 적용:**
* Terrain Shader에서 Simple Layer Material Function을 Rotation Layer로 교체합니다.
* Blend Mask와 Blend Mask Scale Multiplier 값을 적절히 설정합니다.
#### 2.3. Unity에서의 구현 (유사 기법)
* **Height-Based Splat Modify 노드 수정:**
* Height Transition Value가 Material에 자동으로 추가되지 않는 문제를 해결합니다.
* Blackboard에 "Height Sharpness" float 파라미터를 추가하고, "Promote to Final Shader" 및 "Show in Inspector" 설정을 합니다.
* Terrain Blend Height 노드를 제거하고, Height Sharpness 값을 직접 사용하도록 수정합니다.
* **Rotation Layer Subgraph 생성:**
* Unreal Engine과 유사하게 텍스처를 두 번 샘플링하고 UV를 Swizzle하여 회전시킵니다.
* Lerp 노드로 두 샘플을 블렌딩합니다.
* 정상 맵 회전을 위해 Swizzle 노드를 사용합니다.
* 마스크 텍스처 샘플링을 위해 Blend Mask Texture 2D 파라미터와 Mask Channel 드롭다운을 추가합니다.
* Mask Scale Multiplier Vector2 파라미터를 추가하고 UV 좌표를 나눕니다.
* **Terrain Shader 적용:**
* Simple Layer subgraph를 Rotation Layer subgraph로 교체합니다.
* Blend Mask, Mask Channel, Mask Scale Multiplier 값을 설정합니다.
### 3. 결론
* 텍스처 타일링 아티팩트 제거는 셰이더 비용 증가를 수반할 수 있습니다.
* Shader Cost가 없는 비-셰이더 기법을 먼저 고려하는 것이 좋습니다.
* Shader 기법(Rotation Layer)은 텍스처를 90도 회전시켜 블렌딩하는 방식입니다.
* 정상 맵 처리에 유의해야 하며, 마스크 텍스처와 스케일링 조절이 중요합니다.
* 모든 레이어에 복잡한 타일링 제거 기법을 적용할 필요는 없으며, 문제가 되는 레이어에만 적용하는 것이 효율적입니다.