
# 지형 텍스처 타일링 끊김 해소: 고급 기법
이 튜토리얼에서는 지형 텍스처 타일링 문제를 효과적으로 해결하는 새로운 방법을 소개합니다. 기존 방식보다 훨씬 자연스러운 결과물을 얻을 수 있으며, 성능 비용은 유사합니다.
## 1. 기존 방식의 문제점
* **간단한 타일링 제거:** 이전 에피소드(4화)에서 소개된 방법은 타일링을 어느 정도 완화하지만, 특히 원거리에서 여전히 패턴이 눈에 띕니다.
* **불충분한 자연스러움:** 텍스처가 반복적으로 나타나 부자연스러운 느낌을 줍니다.
## 2. 새로운 방법: Inigo Killiz의 기법
Inigo Killiz가 고안한 이 기법은 텍스처 타일링을 거의 완전히 제거하여 훨씬 더 자연스러운 지형을 구현합니다.
* **핵심 아이디어:**
* UV 좌표를 세밀하게 조작하여 텍스처 샘플링을 분산시킵니다.
* 노이즈 텍스처를 활용하여 8가지 영역으로 나누고, 각 영역별로 다른 UV 오프셋을 적용합니다.
* 텍스처 자체의 디테일을 활용하여 블렌딩 마스크를 개선합니다.
## 3. Unity에서의 구현
### 3.1. 서브그래프 설정
* **새로운 서브그래프 생성:** "Layer IQ Tile Break"라는 이름으로 생성합니다.
* **텍스처 샘플러:** 4개의 텍스처 샘플러(Diffuse, Normal, Occlusion, Height)를 준비합니다.
* **MIP 샘플링 모드:** `Gradient`로 설정하여 `DDX`, `DDY` 입력을 활성화합니다. 이는 MIP 레벨 계산에 사용됩니다.
* **샘플러 상태:** `Sampler State` 노드를 사용하여 모든 샘플러에 연결합니다.
* **텍스처 블렌딩:** `Lerp` 노드를 사용하여 텍스처 샘플들을 블렌딩합니다.
* **CSNOH 언패킹:** Unity의 `Unpack CSNOH` 노드를 사용하여 Color, Normal, Smoothness, Occlusion, Height 데이터를 각 채널별로 분리합니다. (이 노드가 없다면, Package Manager에서 Shader Graph Samples의 Terrain Shaders Sample을 가져와야 합니다.)
* **결과 패킹:** `Pack Material` 노드를 사용하여 모든 데이터를 하나의 `Material` 출력으로 묶습니다.
* **출력 설정:** Graph Inspector에서 `Material` (Matrix4), `Color`, `Normal`, `Smoothness`, `Occlusion`, `Height` (Vector3 또는 Float) 등의 출력을 정의합니다.
### 3.2. UV 좌표 생성 및 노이즈 활용
* **레이어 드롭다운:** 4개의 레이어를 가진 `Layer` 드롭다운을 생성합니다.
* **`Terrain Texture` 노드:** Unity 6.3 이상 버전에서 사용 가능하며, 레이어 드롭다운을 연결하여 해당 레이어의 텍스처 애셋을 가져옵니다.
* **텍스처 트랜스폼 분리:** `Split Texture Transform` 노드를 사용하여 타일링 및 오프셋 값을 추출합니다.
* **`Tiling and Offset` 노드:** 추출된 타일링 및 오프셋으로 UV 좌표를 생성합니다.
* **`DDX` 및 `DDY` 노드:** 생성된 UV 좌표를 `DDX` 및 `DDY` 노드에 연결하고, 이를 텍스처 샘플러의 `Derivative` 입력으로 사용합니다.
* **노이즈 텍스처:**
* 64x64 크기의 중간 회색 노이즈 텍스처를 생성합니다. (Filter -> Noise -> Add Noise, Gaussian Monochromatic, Amount 25%)
* Unity에서 텍스처 설정을 `Single channel red`, `Ignore PNG gamma`, `R8`로 변경합니다.
* 이 노이즈 텍스처를 `UV` 좌표에 0.017 배율로 곱하여 지형 전체에 크게 스케일링합니다.
* **마스크 생성:**
* 노이즈 텍스처 UV에 8을 곱합니다.
* `Floor` 노드를 사용하여 0부터 8까지의 정수 값을 얻습니다.
* 이 값을 기반으로 8개의 영역으로 나누어 UV 오프셋을 생성합니다.
### 3.3. UV 오프셋 및 블렌딩
* **UV 오프셋 계산:**
* `Vector2` 노드 (3, 7)을 사용하여 첫 번째 텍스처 세트에 대한 오프셋을 생성합니다.
* 두 번째 텍스처 세트에는 위 값에 1을 더합니다.
* `Sine` 노드를 사용하여 위에서 생성된 오프셋을 기반으로 UV 좌표를 생성합니다. (주기: 6.2로 설정)
* `Offset` float 파라미터와 곱하여 오프셋 양을 조절합니다.
* 이 오프셋 값을 원래 UV 좌표에 더합니다.
* **텍스처 샘플링:** 계산된 UV 좌표를 각 텍스처 샘플러에 연결합니다.
* **마스크 기반 블렌딩:**
* `Fraction` 노드의 결과 (0~8 범위의 정수)를 사용하여 두 세트의 텍스처를 블렌딩합니다.
* (옵션) 텍스처 자체의 밝기와 대비를 활용하여 마스크를 개선합니다.
* 두 텍스처 샘플 간의 차이를 계산합니다.
* RGB 채널 합계를 구합니다.
* 결과를 0.1로 곱합니다.
* 이 값을 원래 마스크에서 빼줍니다.
* `Smooth Step` 노드 (0.2, 0.8)를 사용하여 최종 블렌딩 마스크를 생성합니다.
### 3.4. 샘플러 설정 및 결과 확인
* **샘플러 상태:** `Trilinear` 및 높은 `Anisotropic Filtering`으로 설정하여 텍스처 선명도를 높입니다.
* **블렌드 파라미터:** `Offset` 파라미터를 조절하여 타일링 끊김 정도를 제어합니다.
---
## 4. Unreal Engine에서의 구현
### 4.1. 머티리얼 함수 준비
* **에피소드 4의 회전 레이어 복사:** `LayerIQTileBreak`라는 이름으로 복사하여 시작점으로 사용합니다.
* **노이즈 텍스처:** Unity와 동일한 노이즈 텍스처를 가져옵니다.
* **UV 좌표 생성:**
* 원본 UV에 0.017 배율을 곱하고 `Texture Sample` 노드의 UV로 사용합니다.
* **마스크 생성:**
* 노이즈 텍스처의 Red 채널에 8을 곱합니다.
* `Floor` 노드를 사용하여 0부터 8까지의 정수 값을 얻습니다.
* 이 결과를 `Frac` 노드에 연결하여 두 텍스처 세트 간의 블렌딩 마스크로 사용합니다. (이전 회전 방식과 달리 UV 오프셋에 사용)
### 4.2. UV 오프셋 및 블렌딩
* **UV 오프셋 계산:**
* `Vector2` 노드 (3, 7)을 첫 번째 텍스처 세트의 UV에 곱합니다.
* 두 번째 텍스처 세트에는 1을 더한 후 `Vector2` (3, 7)을 곱합니다.
* `Sine` 노드 (주기: 6.2)를 사용하여 UV 오프셋을 생성합니다.
* `Offset` 스칼라 파라미터를 곱하여 조절합니다.
* 원본 UV에 위에서 계산된 오프셋을 더합니다.
* **텍스처 샘플링:** 계산된 UV 좌표를 각 텍스처 샘플러에 연결합니다.
* **마스크 기반 블렌딩:** `Frac` 노드의 결과 (0~8 범위의 정수)를 두 텍스처 샘플러 간 `Lerp` 노드의 Alpha 값으로 사용합니다.
* **(옵션) 텍스처 자체를 활용한 블렌딩 개선:** Unity와 유사하게 텍스처 간의 차이를 계산하고 조절하여 블렌딩 마스크를 개선합니다.
### 4.3. 결과 확인 및 파라미터 조절
* **머티리얼 인스턴스 생성:** `Offset` 파라미터를 조절하여 타일링 끊김 정도를 실시간으로 확인합니다.
* 0: 타일링 발생
* 1: 최대 타일링 끊김 효과
* **성능:** 이 기법은 이전의 90도 회전 방식과 성능 비용이 거의 동일하지만, 타일링 끊김 효과는 훨씬 뛰어납니다.