ORM·마스크 맵 패커 · Unity·Godot·glTF 채널 패킹
AO·러프니스·메탈릭 등을 엔진이 읽는 채널에 넣으세요. 프리셋마다 채널 순서의 근거를 밝히며, PNG는 랩이 직접 쓰므로 알파 0 아래의 바이트도 남습니다.
채널 패킹은 따로 있는 회색 맵을 엔진이 읽는 순서대로 PNG 한 장의 R·G·B·A에 넣는 일입니다. Unity HDRP 마스크 맵은 R 메탈릭·G 앰비언트 오클루전·B 디테일 마스크·A 스무스니스, Unity URP 채널 패킹 텍스처는 R 메탈릭·G 오클루전·A 스무스니스, glTF 2.0과 Godot 4용 ORM은 R 오클루전·G 러프니스·B 메탈릭입니다. 크기가 같은 회색 맵을 네 장까지 넣고 프리셋을 고르거나 채널을 직접 배치한 뒤, 엔진이 러프니스 대신 스무스니스를 원하는 채널에 "반전"을 체크하고 …-mask.png를 받으세요. 패킹된 바이트는 측정했고 엔진 가져오기는 실행하지 않았습니다.

- Channel PNGs측정 확인· numpy
- Normal map측정 확인· numpy
- Packed mask / ORM측정 확인· Pillow
- Engine import미검증
패커가 채널을 채우는 방식
입력은 텍셀마다 회색 값 하나로 읽힙니다. Rec. 709 휘도, 곧 0.2126 R + 0.7152 G + 0.0722 B를 반올림한 값입니다. 진짜 회색 맵(R = G = B)이면 저장된 값과 정확히 같으므로 회색 바이트가 바뀌지 않고 채널에 들어갑니다. 색이 있는 이미지는 휘도로 섞여 버리는데, 데이터 맵에서 원하는 결과는 거의 아닙니다.
프리셋은 입력이 들어갈 자리만 정합니다. 입력은 넣은 순서대로 의미 있는 채널을 채우고, 배치가 무시하는 채널은 0, 쓰지 않는 알파는 255로 써서 파일이 불투명하게 유지됩니다. 자동 반전은 없습니다. Unity의 스무스니스는 1 − 러프니스이므로 러프니스 맵을 가졌다면 스무스니스 채널에 "반전"(255 − 값)을 체크합니다.
여기서 알파는 데이터입니다. HDRP·URP 텍스처에서 스무스니스 0은 알파 0입니다. 패커는 캔버스가 아니라 자체 인코더로(32줄씩) PNG를 쓰므로 그런 텍셀 아래의 메탈릭·AO 바이트가 살아남습니다. 입력은 브라우저 이미지 디코더로 읽으므로 투명도가 있는 파일보다 평범한 회색 PNG를 넣으세요.
데이터로 가져오세요. Unity HDRP 문서는 마스크 맵의 sRGB (Color Texture)를 끄고 Texture Type을 Default로 두라고, URP 문서는 채널 패킹 텍스처의 sRGB를 끄라고 안내하며, glTF 2.0은 메탈릭·러프니스 값이 리니어여야 한다고 규정합니다.
- 마스크 맵
- Unity HDRP의 패킹 텍스처. R 메탈릭·G AO·B 디테일 마스크·A 스무스니스.
- ORM
- R·G·B에 오클루전·러프니스·메탈릭. glTF 2.0의 순서이며 Godot ORMMaterial3D도 같습니다.
- 상수 채널
- 배치상 맵이 필요 없어 전체를 0이나 255로 쓴 채널.
- 반전
- 255 − 값. 1 − x의 8비트 형태로, 러프니스와 스무스니스를 서로 바꿉니다.
예시: 같은 맵 세 장을 세 가지 배치로
텍셀 하나의 회색 맵 세 장: AO 10, 러프니스 80, 메탈릭 220. 배치 줄은 패커가 보여 주는 형식입니다(숫자 = 넣은 파일, ⁻ = 반전).
ORM (glTF 2.0, Godot 4) 파일: ao, roughness, metallic R←1 · G←2 · B←3 · A←255 → (10, 80, 220, 255)
Unity HDRP 마스크 맵 파일: metallic, ao, roughness R←1 · G←2 · B←0 · A←3⁻ → (220, 10, 0, 175)
Unity URP 패킹 파일: metallic, ao, roughness R←1 · G←2 · B←0 · A←3⁻ → (220, 10, 0, 175)
스무스니스 = 255 − 80 = 175 (1 − 0.314 = 0.686)
랩 측정: ORM 프리셋 (10, 80, 220, 255), 직접 배치 (220, 10, 80, 0), R 반전 (245, 80, 220, 255)디테일 마스크가 없어서 HDRP와 URP 줄이 같습니다. HDRP는 B를 디테일 마스크로 읽고 URP는 무시합니다. HDRP 프리셋에 파일을 세 장만 넣으면 세 번째 파일이 B에 들어가므로, 위처럼 B를 0으로, A를 3번 파일 반전으로 바꾸세요.
회색 맵마다 들어갈 곳
| 가진 회색 맵 | Unity HDRP 마스크 맵 | Unity URP 채널 패킹 | glTF 2.0 / Godot ORM |
|---|---|---|---|
| 메탈릭 | R | R | B |
| 앰비언트 오클루전 | G | G(텍스처를 Occlusion에도 지정하면 읽음) | R |
| 러프니스 | A, 반전(스무스니스) | A, 반전(스무스니스) | G |
| 디테일 마스크 | B | — | — |
| 채널에 넣을 맵이 없음 | 상수 0(예: 디테일 없는 B) | B = 0 | A = 255(사용 안 함) |
Nerulio의 "Unity 메탈릭+스무스니스" 프리셋은 내장 Standard 셰이더 문서(G·B 사용 안 함)를 따라 G에 0을 씁니다. URP에서 오클루전도 쓰려면 직접 배치를 골라 AO 파일을 G에 두세요.
이렇게 작동합니다
- 프리셋: Unity HDRP 마스크(M·AO·디테일·스무스니스), URP 메탈릭(M·–·–·스무스니스), ORM(glTF 2.0·Godot 4).
- 채널별 직접 배치, 상수 0/255, 채널 반전(러프니스 → 스무스니스).
- 캔버스가 아니라 랩이 PNG를 직접 써서 알파 0 아래의 RGB를 유지합니다.
- 프리셋마다 순서의 근거인 문서나 엔진 소스를 연결합니다.
사용 방법
- 회색 맵들을 끌어다 놓습니다.
- 프리셋을 고르거나 채널을 직접 배치합니다.
- 엔진이 반대로 기대하는 채널은 반전합니다.
- 패킹한 PNG를 받습니다.
받게 되는 파일
| 파일 | 용도 |
|---|---|
rock_metallic-mask.png | 패킹한 텍스처. 처음 넣은 파일 이름을 따릅니다. 8비트 RGBA PNG이며 알파 0인 곳의 RGB도 유지됩니다. |
rock_metallic-mask-channels.zip | 선택 확인용: 패킹한 파일을 채널 분리기로 열어 네 평면을 저장하고 입력과 비교합니다. |
패킹한 텍스처를 엔진에서 쓰기
엔진 문서에 있는 단계이며 Nerulio가 이 가져오기를 실행하지는 않았습니다.
- Unity HDRP: PNG를 가져와
sRGB (Color Texture)를 끄고 Texture Type을Default로 둔 뒤, HDRP Lit 머티리얼의 Surface Inputs에서 Mask Map에 지정합니다. 마스크 맵을 지정하면 Metallic·Smoothness·AO Remapping 슬라이더가 나타납니다. - Unity URP:
sRGB (Color Texture)를 끄고 가져와 Lit 머티리얼의 Workflow Mode를Metallic으로 두고, 텍스처를 Metallic Map과 Occlusion Map에 지정한 뒤 Smoothness › Source는 기본값Metallic Alpha로 둡니다. - Godot 4:
ORMMaterial3D를 만들고 ORM PNG를 ORM 텍스처로 지정합니다.StandardMaterial3D도ao_texture_channel을 Red,roughness_texture_channel을 Green,metallic_texture_channel을 Blue로 두면 같은 파일을 읽습니다. - glTF 2.0: ORM 이미지를 머티리얼의 metallicRoughness 텍스처로, 오클루전을 담았다면 오클루전 텍스처로도 참조합니다. 베이스 컬러는 별도의 sRGB 이미지로 둡니다.
결과 확인
- 패킹한 PNG를 같은 배치로 채널 분리기에서 엽니다. 각 평면이 넣은 회색 맵과 같아야 하고(기능 점검에서 ambientCG 회색 맵으로 바이트 동일 확인), 반전한 채널은 255 − 값이어야 합니다.
- 상수 채널은 채널 통계에서 최소 = 최대(0 또는 255)로 보입니다.
- 엔진에서 거친 곳은 흐리게, 연마된 곳은 날카롭게 보여야 합니다. 반대라면 스무스니스 채널을 반전하지 않은 것입니다.
문제 해결
| 증상 | 유력한 원인 | 확인 방법 | 해결 |
|---|---|---|---|
| Unity에서 거친 곳이 매끈해 보임 | 러프니스를 반전 없이 알파에 넣음 | A를 분리하면 255 − 러프니스가 아니라 러프니스 그대로 | A의 "반전"을 체크하고 다시 패킹 |
| 맵이 엉뚱한 채널에 들어감 | 입력은 넣은 순서대로 채널을 채움 | 미리보기 아래 배치 줄(예: R←1 · G←2 · B←3 · A←255) | 채널마다 선택 상자에서 맞는 파일 고르기 |
| "All channel inputs must have the same dimensions" | 회색 맵 하나의 크기가 다름 | 파일 목록에 크기가 나옴 | 모든 맵을 먼저 같은 크기로 내보내기 |
| URP 머티리얼이 주변광에서 어두워짐 | 텍스처를 Occlusion에 지정했는데 Unity 프리셋이 G에 0을 씀 | G를 분리하면 최소 = 최대 = 0 | 직접 배치로 AO 파일을 G에 두거나 Occlusion Map을 비워 두기 |
| 가져온 뒤 전체가 너무 번들거리거나 무광 | 패킹 텍스처를 sRGB 켠 채로 가져옴 | Unity 텍스처의 sRGB (Color Texture) 체크 | sRGB 끄기. 값은 데이터임 |
| 채널 값이 예상과 다름 | 색이 있는 입력이 휘도로 줄어듦 | 입력이 회색이 아님(R·G·B가 다름) | 색이 있는 원본을 먼저 실제 채널로 분리한 뒤 그 평면을 패킹 |
다른 방법
| 방법 | 이럴 때 더 낫습니다 |
|---|---|
| 패킹 없이 Godot 채널 선택 사용 | Godot 전용. StandardMaterial3D가 텍스처 한 장의 원하는 채널에서 맵을 읽으므로, 순서만 다른 기존 패킹 파일은 다시 패킹할 필요가 없습니다. |
| 텍스처링 프로그램의 내보내기 프리셋 | 맵을 그린 도구가 엔진 배치로 바로 내보낼 수 있을 때. Godot 문서는 ORM용으로 Substance Painter와 ArmorPaint(Unreal Engine 프리셋)를 꼽습니다. |
| Shader Graph (Unity) | 어느 프리셋에도 없는 배치를 쓸 때. Unity URP 문서도 채널을 다르게 패킹했다면 Shader Graph를 쓰라고 안내합니다. |
출력 파일과 검증 방법
"측정 확인"은 내려받은 파일을 페이지 밖에서(Pillow·numpy·별도 파서) 다시 열어 그 속성을 측정했다는 뜻입니다. 게임 엔진에서 불러오는 것은 시험하지 않았습니다.
| 대상 | 파일 | 검증 |
|---|---|---|
| Channel PNGs | <name>-r/g/b/a.png (8-bit grey) | 측정 확인 numpy채널마다 바이트가 같고 완전히 투명한 텍셀 아래의 RGB도 유지됩니다. |
| Normal map | PNG · OpenGL (+Y) or DirectX (−Y) | 측정 확인 numpy디코딩한 벡터가 단위 길이(최대 오차 0.0002)이고, OpenGL과 DirectX는 초록 채널만 다릅니다. |
| Packed mask / ORM | Unity HDRP mask · URP metallic · ORM (glTF, Godot) | 측정 확인 Pillow패킹된 바이트 확인: ORM 프리셋, AO 10 / 러프니스 80 / 메탈릭 220 → (10, 80, 220, 255). |
| Engine import | Unity · Unreal · Godot | 미검증어떤 엔진에서도 불러오지 않았습니다. |
검증 근거
채널 분리가 네 채널 모두 바이트 동일(최대 차이 0), 투명 텍셀 2048개가 RGB 유지. 가장자리 번짐은 알파 0인 텍셀 448개만 바꾸고 알파 바이트는 하나도 건드리지 않음. OpenGL ↔ DirectX는 초록(255 − g)만 다름. 변환한 노멀은 단위 벡터.
한계
- 정확한 채널 바이트는 PNG에서만 보장됩니다. JPEG·WebP는 브라우저가 디코딩하며 "바이트 동일 아님"으로 표시합니다.
- 인터레이스 PNG와 16비트 출력은 지원하지 않습니다. 정확 경로는 3,355만 픽셀까지입니다.
- 노멀맵의 규약은 픽셀로 알아낼 수 없고 변환만 할 수 있습니다.
- Unity·Unreal·Godot에서 불러오지 않았습니다. 채널 순서는 각 문서와 엔진 소스에 근거합니다.
버전과 출처
텍스처 랩에서 측정(docs/TEXTURE-LAB.md): AO 10 / 러프니스 80 / 메탈릭 220에 ORM 프리셋을 쓰면 랩 안에서도 이 페이지에서도 (10, 80, 220, 255). 직접 배치는 (220, 10, 80, 0), R 반전은 (245, 80, 220, 255). 브라우저 기능 점검은 ambientCG 회색 맵 세 장을 패킹해 채널마다 입력과 바이트가 같음을 확인합니다. 배치는 아래 문서(Godot ORM 순서는 엔진 소스)에서 왔으며 엔진 가져오기는 실행하지 않았습니다.
참고한 공식 문서
자주 묻는 질문
Unreal ORM 순서는 공식인가요?
Epic은 R=AO·G=러프니스·B=메탈릭 순서를 문서화하지 않았습니다. ORM 프리셋은 glTF 2.0을 따르며 그렇게 표시합니다.
엔진에서 불러와 봤나요?
아니요. 패킹된 바이트는 확인했습니다(예: ORM 프리셋 (10, 80, 220, 255)). Unity·Unreal·Godot 가져오기는 시험하지 않았습니다.
무료인가요? 계정이 필요한가요?
이 페이지의 기능은 모두 무료이며 계정 없이 쓸 수 있습니다. 워터마크나 막혀 있는 내보내기가 없습니다.
스프라이트가 업로드되나요?
아니요. Studio는 이 브라우저 탭 안에서 디코딩·패킹·내보내기를 합니다. 프로젝트는 브라우저(IndexedDB)에 자동 저장되며 .nerulio 파일로 저장할 수 있습니다.
Aseprite나 엔진 플러그인을 설치해야 하나요?
아니요. .aseprite 파일은 브라우저에서 읽고 씁니다. 엔진별 번들에는 그 엔진에 필요한 것이 들어 있습니다(Godot는 가져오기 설정과 씬, Unity와 Godot 타일셋은 작은 편집기 스크립트).