타일 노멀맵 이음새 없애기 · 반복(Wrap) 생성
반복 텍스처 경계를 따라 밝거나 어두운 줄이 보이면, 대개 노멀맵을 만들 때 테두리를 가장자리로 취급한 것입니다. 커널이 반대편 픽셀을 읽지 않고 테두리에서 멈춰(clamp), 표면이 그냥 이어져야 할 곳에 경사가 생긴 것입니다.
반복되는 노멀맵의 이음매에 줄이 보이는 원인은 세 가지 중 하나입니다. 노멀맵을 만들 때 이미지 테두리를 가장자리로 취급했거나(커널이 반대편을 읽지 않고 고정(clamp)됨), 색이나 하이트 텍스처 자체가 반복되지 않거나, 엔진이 텍스처를 반복하지 않는 경우입니다. 반복(Wrap) 가장자리로 맵을 만들고, 반만큼 밀린 텍스처로 만든 맵이 같은지 확인한 뒤, 조명을 움직이며 3×3으로 보세요. Nerulio Studio 텍스처 작업 공간은 투명 픽셀이 없는 그림에 반복을 제안하며, 테두리가 안쪽과 똑같이 계산되면 반복 검사가 0을 표시합니다.

- Godot 4 2D lights검증됨· Godot 4.7.2
- Unity 6 URP 2D검증됨· Unity 6000.5.3f1 (URP 17.5)
- PNG set + JSON일반 파일
이음매가 생기는 이유
노멀맵 생성기는 픽셀마다 이웃과의 차이로 기울기를 잽니다. 이미지 테두리에서는 이웃의 절반이 없습니다. 고정(Clamp)은 테두리 픽셀을 대신 되풀이하므로 마지막 한두 열의 기울기가 작아지거나 틀어지고, 반복(Wrap)은 반대편 픽셀, 곧 텍스처가 반복될 때 테두리 옆에 실제로 놓이는 픽셀을 읽습니다. 범위가 넓은 커널(Sobel 5×5는 2px)이나 경사·블러 단계는 손상된 띠를 넓힙니다. Laigter 1.14 기본값은 ambientCG 벽돌의 사방에 3px 기울어진 띠를 남겼습니다.
가장자리가 맞지 않는 것은 다른 문제입니다. 알베도의 마지막 열이 그림 안에서 이웃한 열끼리보다 첫 열과 더 크게 다르면 그림이 반복되지 않는 것이고, 어떤 노멀맵도 이를 가릴 수 없습니다. Nerulio의 알베도 이음새 비율이 바로 이 두 값을 비교합니다. 1 정도면 보이는 이음새가 없고, 랩과 Studio는 두 방향 모두 1.5 이하일 때 이음새 없음으로 봅니다.
엔진도 반복해야 합니다. Unity의 Wrap Mode Clamp는 반복하지 않고 "텍스처 가장자리를 늘리며", Godot의 BaseMaterial3D.texture_repeat는 기본으로 켜져 있고, glTF 2.0 샘플러의 기본값은 반복입니다. 고정된 텍스처는 가는 줄보다는 늘어난 가장자리로 보입니다.
모든 줄이 텍스처에 있는 것은 아닙니다. 타일 경계가 아니라 모델의 UV 이음새를 따라가는 줄은 메시(UV나 탄젠트)에서 생기며, 텍스처를 바꿔서는 고칠 수 없습니다.
- 고정(Clamp)
- 이미지 밖의 샘플이 테두리 픽셀을 씀. 스프라이트에는 맞고 반복 텍스처에는 틀립니다.
- 반복(Wrap)
- 이미지 밖의 샘플을 다음 타일처럼 반대편에서 가져옴.
- 반복(롤) 검사
- 텍스처를 반만큼 밀어 맵을 만들고, 결과를 되돌려 2px 테두리 띠를 비교. 0이면 반복 정확.
- 이음새 비율
- 반복 경계를 건너는 차이 ÷ 이미지 안 이웃 사이의 차이.
예시: 경계를 넘어 이어져야 할 기울기
픽셀마다 10단계씩 오르는 하이트 경사가 256px 텍스처의 반복 경계를 그대로 지나갑니다. 중앙 차분(Studio의 Pixel 커널)으로 계산하면:
하이트 x=254: 100 x=255: 110 | x=0: 120 x=1: 130 안쪽 기울기 = 픽셀당 10
Wrap x=255: (h[0] − h[254]) / 2 = (120 − 100) / 2 = 10 x=0: (h[1] − h[255]) / 2 = 10
Clamp x=255: (h[255] − h[254]) / 2 = (110 − 100) / 2 = 5 x=0: (h[1] − h[0]) / 2 = 5
→ Clamp는 이음매 양쪽 두 열의 기울기를 절반으로 만듦: 반복마다 2px 줄
ambientCG 벽돌의 롤 오차 (0 = 반복 정확), 2026-09-24:
Nerulio (Wrap) 0 · Laigter 1.14 기본 63.8, Tile 프리셋 0 · PBR Forge 0.57, Tile 0.24 · NormalMap-Online 0같은 벽돌에서 Nerulio 노멀맵의 경계를 건너는 차이는 안쪽 차이의 1.19배였고, Laigter 기본값은 24.0배였습니다. 반복되는 텍스처와 반복을 정확히 처리하는 생성기라면 이 비율이 1 가까이 유지됩니다.
이렇게 작동합니다
- 투명 픽셀이 없는 그림은 “타일 텍스처”로 제안되고, 가장자리 방식이 반복(Wrap)이 됩니다. 모든 커널이 경계를 넘어 반대편 픽셀을 읽습니다.
- 검사 패널의 반복 검사는 텍스처를 반만큼 밀어 맵을 다시 만들고 비교합니다. 0이면 이음새가 없습니다.
- 알베도 자체의 이음새 비율(1 ≈ 보이는 이음새 없음)로 그림이 원래 반복되지 않는 경우를 알려 줍니다. 색에 있는 이음새는 노멀맵으로 가릴 수 없습니다.
- 3×3 타일 보기(T)로 조명된 텍스처를 반복해 놓고, 조명을 경계 위로 옮기며 줄이 있는지 봅니다.
- 높이 맵도 같습니다. 8비트 벽돌 높이 맵에서 반복으로 만든 결과가 ambientCG 자체 노멀맵과 8.8°(높이 맵으로 읽으면 7.7°) 차이였고, 롤 오차는 0이었습니다.
사용 방법
- 텍스처 작업 공간에 반복 텍스처(또는 높이 맵)를 넣습니다.
- “타일 텍스처”를 그대로 두거나, 노멀 맵 패널에서 가장자리를 반복으로 정합니다.
- 검사 패널에서 반복 검사가 0인지 보고, 알베도 이음새 비율이 높으면 그림부터 고칩니다.
- T로 3×3 보기를 켜고 Lit으로 바꾼 뒤 조명을 경계 위로 끌어 봅니다.
- Godot 4, Unity 6 또는 PNG 세트로 내보냅니다.
결과 확인
- Studio › 검사 › 이음새: 반복 검사가 테두리 차이의 평균과 최대를 보여 주며, 0.01 미만이면 ✓ 반복 정확이 나옵니다.
- T로 3×3 보기를 켜고 Lit으로 바꾼 뒤 조명을 경계 위로 끕니다. 타일 경계를 따라가는 줄이 없어야 합니다.
- 엔진에서 머티리얼을 3×3 이상 반복하고 조명을 반복 경계 위로 옮깁니다. 노멀맵을 끄고도 똑같이 해 보면 색 이음새와 조명 이음새를 구별할 수 있습니다.
가장자리 방식과 경계에서 생기는 일
| 가장자리 방식 | 쓰는 곳 | 텍스처를 반복하면 |
|---|---|---|
| 고정(Clamp) | 투명한 윤곽이 있는 스프라이트 | 테두리 픽셀을 되풀이해 이음매에서 경사가 끊기고 밝은 줄이 보임 |
| 반복(Wrap) | 타일 텍스처(투명 픽셀이 없으면 제안) | 반대편에서 샘플링, 반복 검사 0, 줄 없음 |
| 반사(Mirror) | 반복하지 않지만 테두리가 생기면 안 되는 그림 | 경계에서 다음 타일이 아닌 반사를 읽어 희미한 줄이 남을 수 있음 |
| 반복이지만 알베도에 이음새 | 해당 없음: 알베도부터 고치기 | 노멀맵은 매끈해도 색에 이음매가 보임 |
같은 CC0 벽돌에서의 롤 오차(0 = 반복 정확): Nerulio 0 · Laigter 1.14 기본 63.8, Tile 프리셋 0 · PBR Forge 0.57, Tile 0.24 · NormalMap-Online 이 에셋에서 0.
문제 해결
| 증상 | 유력한 원인 | 확인 방법 | 해결 |
|---|---|---|---|
| 텍스처가 반복되는 곳에만 밝거나 어두운 줄, 노멀맵을 켰을 때만 | 테두리에서 고정(Clamp)으로 맵을 만듦 | Studio › 검사 › 이음새에서 반복 검사가 0보다 큼 | 가장자리 = 반복(타일 텍스처)으로 다시 만들기. ✓ 반복 정확이 나와야 함 |
| 노멀맵을 꺼도 줄이 남음 | 알베도나 하이트 맵 자체가 반복되지 않음 | 알베도 이음새 비율이 1보다 훨씬 크거나 심리스 타일 검사기로 확인 | 그림부터 고치기. Nerulio가 반복되지 않는 그림을 반복되게 만들 수는 없음 |
| 네 테두리 모두를 따라 2~3px 폭의 띠 | 생성기가 테두리를 스프라이트 가장자리로 봄(경사·가장자리 검출) | 노멀맵만 보면 띠가 사방에서 바깥으로 기울어 있음 | 생성기의 타일 모드를 쓰거나 여기서 반복으로 다시 만들기 |
| 가장자리가 늘어나 보이고 텍스처가 반복되지 않음 | 엔진이 텍스처를 반복하지 않고 고정함 | Unity: Wrap Mode, Godot: 머티리얼의 texture_repeat | Wrap Mode를 Repeat로, 또는 texture_repeat를 켜기 |
| 반사(Mirror) 가장자리로 만들었더니 희미한 줄 | 반사는 다음 타일 대신 뒤집힌 픽셀을 읽음 | 노멀 맵 패널의 가장자리 설정 | 반복되는 텍스처에는 반복(Wrap) 사용 |
| 줄이 타일 경계가 아니라 모델의 UV 이음새를 따라감 | 메시의 UV 배치나 탄젠트 | 3D 프로그램에서 UV를 보면 줄이 UV 섬 가장자리에 있음 | 메시에서 고치기. 원인은 텍스처가 아님 |
| 이미 있는 노멀맵에 이음새가 있음 | 다른 곳에서 고정 가장자리로 만든 맵 | 가져온 맵에 검사 패널 실행 | Nerulio는 기존 맵을 덧대어 고치지 않음. 알베도나 하이트에서 반복으로 다시 만들기 |
다른 방법
| 방법 | 이럴 때 더 낫습니다 |
|---|---|
| 텍스처 랩 노멀 단계의 반복 | 하이트 → 노멀 변환 한 번만 빨리 할 때. 고급에서 반복(Wrap)을 체크하거나 wrap=1로 열며, 보정 › 이음선 검사로 알베도를 잽니다. |
| Laigter의 Tile 프리셋 | 이미 Laigter를 쓰고 있을 때. Tile 프리셋은 벽돌의 롤 오차를 63.8에서 0으로 줄였습니다. |
| 3D 프로그램에서 형상으로 굽기 | 표면을 3D로 모델링했을 때. 반복 메시에서 구운 맵은 이미지 테두리 처리와 전혀 상관이 없습니다. |
엔진별 내보내기와 검증 방법
"검증됨"은 실제 CC0 에셋으로 내보낸 파일을 해당 엔진·도구가 직접 불러와 원본과 비교했다는 뜻입니다. 불러오지 않은 형식은 그렇게 표시합니다.
| 대상 | 파일 | 검증 |
|---|---|---|
| Godot 4 2D lights | _lit.tscn · CanvasTexture .tres · normal / specular PNG | 검증됨 Godot 4.7.2실제 CC0 사례 6개를 Godot(gl_compatibility)가 렌더링했고, 확인한 모든 프레임이 Studio 조명 미리보기와 1/255 이내로 같았습니다. 초록을 뒤집은 같은 렌더는 3.8~37단계 어긋나므로 잘못된 규약을 잡아낼 수 있습니다. |
| Unity 6 URP 2D | PNG · nerulio-texture.json · Editor/NerulioNormalMapImporter.cs | 검증됨 Unity 6000.5.3f1 (URP 17.5)12회 중 12회 통과(사례 6개 × 감마·리니어 색 공간): URP가 적용한 조명이 내보낸 노멀맵과 일치합니다(평균 오차 0.0037~0.0085). 빛의 감쇠는 URP 방식이라 밝기는 미리보기가 아니라 Unity 기준입니다. |
| PNG set + JSON | albedo · _n (OpenGL) · _n_dx (DirectX) · 16-bit height · AO · specular · manifest | 일반 파일어떤 엔진이나 도구에서도 쓰는 일반 파일이며, 엔진 실행 검증은 주장하지 않습니다. |
검증 근거
Godot 4.7.2가 실제 CC0 사례 6개(도트, HD 스프라이트, 반복 텍스처, 가져온 DirectX 맵)를 렌더링했고 확인한 모든 프레임이 Studio 미리보기와 1/255 이내였습니다. Unity 6000.5 URP 2D: 12회 중 12회 통과(사례 6개 × 감마·리니어). 규약을 아는 실제 맵으로 OpenGL/DirectX 판별: 1K 전체 맵 128개 100% 정답, 표본 1,562개 중 틀린 "높음" 판정 0건(초록이 밝으면 OpenGL이라는 단순 규칙은 46%).
한계
- 투명한 가장자리가 없는 그림(반복 텍스처)에서는 빨강이 뒤집힌 것과 DirectX 초록을 구별할 수 없습니다. 점검 패널이 이를 알리고 "빨강 뒤집기"를 제공합니다.
- 시트는 스프라이트 작업 공간에서 프레임을 자르기 전까지 그림 하나로 조명됩니다. 텍스처 작업 공간은 프레임을 자르지 않습니다.
- 림 라이트는 미리보기 전용이며, Unity로는 스페큘러 맵을 내보내지 않습니다(Godot는 내보냄).
- Unity는 자체 빛 감쇠를 씁니다. 내보낸 노멀맵은 Unity에서 검증했지만 밝기 곡선은 Unity 방식입니다.
버전과 출처
Studio 텍스처 작업 공간의 내보내기는 Godot 4.7.2(6/6 사례 통과, 최대 차이 1/255)와 Unity 6000.5.3f1·URP 17.5(12/12 통과)에서 불러와 렌더링했으며, 반복으로 만든 ambientCG 벽돌 타일 사례도 포함됩니다(docs/STUDIO-TEXTURE.md). 이음새와 롤 수치는 같은 CC0 벽돌로 한 2026-09-24 비교에서 나왔습니다. 엔진의 반복 설정은 Unity 6·Godot 4.7·glTF 2.0 문서에서 인용했습니다.
참고한 공식 문서
자주 묻는 질문
노멀맵을 만든 뒤에야 이음새가 생긴 이유는?
색은 반복되지만 생성기가 테두리를 스프라이트 가장자리로 보고 마지막 픽셀에 경사나 테두리를 넣었기 때문입니다. 예를 들어 Laigter 기본값은 사방에 3px 기울어진 띠를 남기고, Tile 프리셋을 쓰면 없어집니다.
이미 이음새가 있는 노멀맵을 고칠 수 있나요?
아니요. 알베도나 높이 맵에서 반복 모드로 다시 만드세요. Studio는 기존 노멀맵의 경계를 덧대어 고치지 않습니다.
반사(Mirror)는 언제 쓰나요?
반복하지는 않지만 테두리에 경사가 생기면 안 되는 그림에 씁니다. 반복 텍스처에 쓰면 다음 타일 대신 반사된 픽셀을 읽어 희미한 줄이 남을 수 있습니다.
반복 검사는 0인데 줄이 보여요.
그렇다면 줄은 색에 있습니다. 알베도 이음새 비율을 보거나 심리스 타일 검사기로 그림을 확인해, 알베도를 고친 뒤 다시 만드세요.
무료인가요? 계정이 필요한가요?
이 페이지의 기능은 모두 무료이며 계정 없이 쓸 수 있습니다. 워터마크나 막혀 있는 내보내기가 없습니다.
스프라이트가 업로드되나요?
아니요. Studio는 이 브라우저 탭 안에서 디코딩·패킹·내보내기를 합니다. 프로젝트는 브라우저(IndexedDB)에 자동 저장되며 .nerulio 파일로 저장할 수 있습니다.
Aseprite나 엔진 플러그인을 설치해야 하나요?
아니요. .aseprite 파일은 브라우저에서 읽고 씁니다. 엔진별 번들에는 그 엔진에 필요한 것이 들어 있습니다(Godot는 가져오기 설정과 씬, Unity와 Godot 타일셋은 작은 편집기 스크립트).