유니티 2D 노말맵 · URP 세컨더리 텍스처 자동 설정
유니티 2D 노말맵이 안 먹힐 때는 대개 네 가지 중 하나가 빠져 있습니다. URP와 2D 렌더러, 조명을 받는 스프라이트 머티리얼, _NormalMap이라는 이름의 세컨더리 텍스처, 노멀맵을 켠 Light2D입니다. 텍스처 작업 공간은 노말맵을 만들고, 텍스처 쪽 설정을 대신 해 주는 에디터 스크립트를 함께 내보냅니다. Unity 6에서 Gamma·Linear 프로젝트 모두 예측한 조명대로 그려졌습니다.

- Unity 6 URP 2D검증됨· Unity 6000.5.3f1 (URP 17.5)
- Godot 4 2D lights검증됨· Godot 4.7.2
- PNG set + JSON일반 파일
이렇게 작동합니다
- Tools › Nerulio › Apply Texture JSON이 스프라이트 영역을 나누고 노말맵을 세컨더리 텍스처 _NormalMap으로 붙입니다. sRGB 끔, 무압축, 밉맵 없음, 2의 거듭제곱 크기 변경 없음.
- Tools › Nerulio › Create Lit Preview가 스프라이트와 Studio 조명마다 점 Light2D를 하나씩 만들고, Normal Map 품질 Accurate, Normal Map Distance = z ÷ Pixels Per Unit으로 맞춥니다.
- Pixels Per Unit은 nerulio-texture.json 안의 숫자(기본 100)이며, 조명 위치·반경·거리가 이 값으로 나뉩니다.
- Unity README는 도트 게임에 Light Render Texture Scale을 안내합니다. 새 2D 렌더러에서 0.5라 조명 해상도가 절반이 됩니다.
- Unity 6000.5.3f1, URP 17.5, 2D 렌더러에서 12/12 통과(실제 에셋 6건 × Gamma·Linear), 평균 오차 0.0037~0.0085.
- 노말맵은 유니티가 읽는 OpenGL 방식(Y+)입니다. 다른 툴에서 받은 DirectX 노말맵은 쓰기 전에 점검 패널로 판별할 수 있습니다.
사용 방법
- 스프라이트나 시트를 넣습니다(시트는 스프라이트 작업 공간에서 먼저 자릅니다).
- 베벨을 맞추고 조명을 놓은 뒤, C로 평면·조명 화면을 나눠 비교합니다.
- 내보내기(Ctrl+E)에서 Unity 6 URP 2D를 체크합니다.
- unity 폴더를 Assets/에 복사하고 에디터 스크립트가 컴파일되기를 기다립니다.
- Tools › Nerulio › Apply Texture JSON을 실행한 다음 Create Lit Preview를 누릅니다.
유니티 2D 노말맵 설정
| 설정 | 임포터가 넣는 값 | 안 맞으면 생기는 일 |
|---|---|---|
| 세컨더리 텍스처 이름 | 알베도 스프라이트에 _NormalMap | 다른 이름이면 라이트용 스프라이트 셰이더가 읽지 않음 |
| sRGB (Color Texture) | 끔 — 색이 아니라 벡터 | 감마 변환이 걸려 요철 방향이 틀어짐 |
| Non-Power of 2 | None | 96×64가 128×64로 늘어나 노멀이 흐려짐(평균 오차 0.005 대신 0.045) |
| 압축·밉맵 | 무압축, 밉맵 끔 | 압축되거나 평균된 텍셀은 내보낸 벡터와 달라짐 |
| Max Size | 시트에 맞게 올림(2048~16384) | 기본 2048이면 큰 시트가 줄어듦 |
| Light2D 노멀맵 | 품질 Accurate, Distance = z ÷ Pixels Per Unit | 노멀맵이 꺼지면 무시되고, 거리가 틀리면 요철이 납작하거나 과해짐 |
| Light Render Texture Scale | 그대로 둠(프로젝트 설정), README에서 1 권장 | 0.5면 작은 스프라이트의 조명이 계단처럼 보임 |
표는 Unity 6000.5.3f1과 URP 17.5에서 배포 임포터가 한 일입니다. 다른 Unity·URP 버전은 돌려 보지 않았습니다.
엔진별 내보내기와 검증 방법
"검증됨"은 실제 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 방식입니다.
자주 묻는 질문
유니티 2D 노말맵이 왜 안 먹히나요?
순서대로 확인하세요. 프로젝트가 2D 렌더러를 쓰는 URP인지, 스프라이트 머티리얼이 Sprite-Lit-Default인지, 노말맵이 정확히 _NormalMap이라는 이름의 세컨더리 텍스처인지, Light2D의 노멀맵이 켜져 있는지. 텍스처 쪽은 임포터가 맡고, 파이프라인·머티리얼·직접 둔 조명은 직접 설정해야 합니다.
도트 그림에 조명이 뭉개지고 계단처럼 보여요.
2D 렌더러는 기본으로 조명을 절반 해상도로 계산합니다(Light Render Texture Scale 0.5). 2D 렌더러 에셋에서 1로 바꾸세요. 프로젝트 설정이라 내보내기는 건드리지 않으며, 검증 때는 1로 두었습니다.
Unity 6에서 고치기 전에는 뭐가 문제였나요?
검증 중에 찾은 우리 임포터의 버그 세 개입니다. Unity 6가 Light2D를 Unity.RenderPipelines.Universal.2D.Runtime 어셈블리로 옮겨서 미리보기에 조명이 안 생겼고, URP 17에서 Normal Map Distance·Quality가 읽기 전용이라 이제 SerializedObject로 설정하며, 96×64 노말맵이 128×64로 늘어나 흐려졌습니다(평균 오차 0.045 → 크기 변경 None으로 0.005).
밝기도 Studio와 똑같나요?
아니요. 위치·색·높이·세기는 Studio 값이지만 감쇠는 URP가 자체 곡선으로 그려서 밝기 곡선은 유니티 것입니다. 검증은 노말맵 항(N·L)을 비교했고, 전체 밝기는 비교하지 않았습니다. Unity에는 스페큘러 맵도 가지 않습니다.
무료인가요? 계정이 필요한가요?
이 페이지의 기능은 모두 무료이며 계정 없이 쓸 수 있습니다. 워터마크나 막혀 있는 내보내기가 없습니다.
스프라이트가 업로드되나요?
아니요. Studio는 이 브라우저 탭 안에서 디코딩·패킹·내보내기를 합니다. 프로젝트는 브라우저(IndexedDB)에 자동 저장되며 .nerulio 파일로 저장할 수 있습니다.
Aseprite나 엔진 플러그인을 설치해야 하나요?
아니요. .aseprite 파일은 브라우저에서 읽고 씁니다. 엔진별 번들에는 그 엔진에 필요한 것이 들어 있습니다(Godot는 가져오기 설정과 씬, Unity와 Godot 타일셋은 작은 편집기 스크립트).