스프라이트 시트 노멀맵 · 프레임마다 따로 생성
노멀맵 생성기를 스프라이트 시트 전체에 돌리면 애니메이션이 아니라 그림 한 장으로 봅니다. 가까이 붙은 프레임끼리 블러와 가장자리 거리가 섞여, 같은 동작도 옆 프레임에 따라 입체감이 달라집니다. 여기서는 스프라이트 작업 공간에서 먼저 프레임을 자르고, 텍스처 작업 공간이 프레임마다 같은 px 설정으로 따로 노멀맵을 만들어 재생 중에도 입체감이 흔들리지 않습니다.

- Godot 4 2D lights검증됨· Godot 4.7.2
- Unity 6 URP 2D검증됨· Unity 6000.5.3f1 (URP 17.5)
- PNG set + JSON일반 파일
이렇게 작동합니다
- 프레임은 스프라이트 작업 공간(적용)에서 옵니다. 텍스처 작업 공간은 직접 자르지 않고, 프레임이 없는 시트는 그림 한 장으로 비춥니다.
- 거리 변환·블러·커널이 프레임 경계를 넘어 읽지 않습니다. tests/normals.test.mjs가 프레임의 맵이 이웃과 무관하고 스프라이트와 함께 움직이는지 확인합니다.
- 베벨 폭·깊이·디테일은 절대 px 값이라 프레임마다 다시 맞추지 않습니다. 128px 이하 도트 프레임에는 1.5px 테두리를 제안합니다.
- 조명 위치는 프레임 px 기준이라 모든 프레임이 똑같이 비칩니다. Enter는 조명 켠 채 재생, `는 시트 전체와 한 프레임 보기를 오갑니다.
- 높이 브러시(B)의 한 획은 시작한 프레임 안에만 남고, 실행 취소 한 번 단위입니다.
사용 방법
- 스프라이트 시트를 넣으면 스프라이트 작업 공간에서 열립니다.
- 격자와 애니메이션을 확인하고 적용을 누릅니다.
- 텍스처 탭을 열면 모든 프레임의 노멀맵이 바로 만들어집니다.
- 베벨과 디테일을 맞추고 조명 도구(L)로 빛을 놓은 뒤 Enter로 조명 속 애니메이션을 봅니다.
- 내보내기(Ctrl+E)에서 Godot 4, Unity 6 URP 2D, PNG 세트 중 하나를 고릅니다.
시트 통째 처리와 프레임별 처리 비교
| 시트 전체를 한 번에 | 프레임별(이 작업 공간) | |
|---|---|---|
| 프레임 경계 근처의 베벨 | 가장자리 거리가 옆 프레임까지 닿을 수 있음 | 각 프레임 안에서만 측정 |
| 블러와 디테일 | 옆 프레임으로 번질 수 있음 | 프레임 경계에서 멈춤 |
| 두 프레임의 같은 그림 | 입체감이 달라질 수 있음 | 같은 입체감, 스프라이트와 함께 이동 |
| 조명 위치 | 시트 px 기준: 위치가 다른 프레임은 다르게 비침 | 프레임 px 기준: 모든 프레임이 똑같이 비침 |
| 내보내기 | 노멀맵 이미지 한 장, 엔진 설정은 직접 | AnimationPlayer가 든 Godot 씬, 유니티 스프라이트 영역+_NormalMap |
엔진별 내보내기와 검증 방법
"검증됨"은 실제 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 방식입니다.
자주 묻는 질문
시트 전체로 노멀맵 하나를 만들면 안 되나요?
프레임이 붙어 있거나 가까우면 시트 전체를 한 번에 처리할 때 블러와 가장자리 거리가 옆 프레임으로 넘어가, 같은 그림도 이웃에 따라 입체감이 달라지고 애니메이션이 번쩍거립니다. 프레임별로 처리하면 시트 어디에 있든 같은 결과가 나옵니다.
Godot 내보내기에서 애니메이션도 재생되나요?
네. <이름>_lit.tscn에 CanvasTexture를 쓴 Sprite2D, 주변광용 CanvasModulate, 조명마다 PointLight2D, 프레임을 넘기는 AnimationPlayer가 들어 있습니다. Godot 4.7.2 렌더링은 그 AnimationPlayer를 거친 경우를 포함해 확인한 모든 프레임에서 Studio 기준과 1/255 이내로 같았습니다.
유니티에서는요?
Unity 6 URP 2D 번들은 JSON으로 스프라이트 영역을 잡고 노멀맵을 _NormalMap 보조 텍스처(선형, 무압축, 리샘플링 없음)로 붙입니다. Unity 6000.5.3f1에서 12번 모두 통과했고, 밝기 곡선은 URP 자체의 것입니다.
무료인가요? 계정이 필요한가요?
이 페이지의 기능은 모두 무료이며 계정 없이 쓸 수 있습니다. 워터마크나 막혀 있는 내보내기가 없습니다.
스프라이트가 업로드되나요?
아니요. Studio는 이 브라우저 탭 안에서 디코딩·패킹·내보내기를 합니다. 프로젝트는 브라우저(IndexedDB)에 자동 저장되며 .nerulio 파일로 저장할 수 있습니다.
Aseprite나 엔진 플러그인을 설치해야 하나요?
아니요. .aseprite 파일은 브라우저에서 읽고 씁니다. 엔진별 번들에는 그 엔진에 필요한 것이 들어 있습니다(Godot는 가져오기 설정과 씬, Unity와 Godot 타일셋은 작은 편집기 스크립트).