본문으로 건너뛰기

텍스처 채널 분리 · RGBA·ORM을 회색 맵으로

브라우저 캔버스로 읽은 패킹 텍스처는 알파 0 아래의 모든 바이트를 잃습니다. 텍스처 랩은 PNG를 직접 디코딩하므로 각 채널이 저장된 그대로 나옵니다.

채널 패킹 텍스처는 서로 무관한 회색 맵을 최대 네 장까지 R·G·B·A 채널에 담습니다. ORM 텍스처는 R·G·B에 오클루전·러프니스·메탈릭을, Unity HDRP 마스크 맵은 메탈릭·AO·디테일 마스크·스무스니스를 담습니다. 분리한다는 것은 채널마다 바이트 하나 바꾸지 않고 단일 채널 이미지로 쓰는 일입니다. 채널 분리기는 PNG를 직접 읽어 고른 배치(HDRP·URP·glTF·Godot ORM·Unreal ORM)에 따라 채널에 이름을 붙이고, 채널을 반전(스무스니스 ↔ 러프니스)할 수 있으며, 완전히 투명한 텍셀 아래까지 원본과 바이트가 같은 8비트 회색 PNG로 저장합니다.

텍스처 맵을 끌어다 놓으세요(PNG는 채널 바이트를 그대로 유지)
브라우저에서 처리하며 파일은 업로드되지 않습니다.
텍스처 랩: CC0 텍스처로 만든 노멀맵과 OpenGL/DirectX 규약 표시
CC0 에셋(ambientCG)을 연 실제 텍스처 랩 화면입니다.
출력
  • Channel PNGs측정 확인· numpy
  • Normal map측정 확인· numpy
  • Packed mask / ORM측정 확인· Pillow
  • Engine import미검증

패킹 텍스처 안에 든 것과 순서가 중요한 이유

패킹 텍스처의 각 채널은 텍셀마다 독립된 0~255 숫자이지 색의 일부가 아닙니다. 그림으로 보면 이상한 색으로 보이고, G가 러프니스(glTF·Godot ORM)인지 앰비언트 오클루전(Unity HDRP)인지 오클루전(Unity URP)인지는 배치를 알아야 압니다. 파일 이름으로는 순서를 알기 어렵습니다. _ORM·_ARM·_MaskMap·_packed는 모두 "패킹됨"이라는 뜻일 뿐이라, 랩은 모두 패킹 맵으로 분류하고 배치는 직접 고르게 합니다.

데이터를 잃는 곳은 알파 채널입니다. Unity 마스크 맵에서 완전히 거친 텍셀은 스무스니스가 0, 곧 알파가 0입니다. 브라우저 캔버스는 픽셀을 미리 곱해 보관하므로 그 텍셀의 메탈릭·AO·디테일 바이트가 0으로 돌아옵니다. 분리기는 자체 리더로 PNG를 디코딩하고(인터레이스가 아닌 모든 색 형식, 1~16비트, tRNS) 채널마다 색 변환 없이 텍셀당 1바이트인 색 형식 0 PNG로 씁니다.

반전은 정확합니다. 저장되는 값은 255 − 값이며, 두 번 반전하면 원래 바이트로 돌아옵니다. Unity의 스무스니스 채널은 이렇게 다른 엔진이 원하는 러프니스가 됩니다.

채널 평면
한 채널의 w × h 바이트. 회색 PNG로 저장됩니다.
미리 곱한 알파
알파를 이미 곱한 색. 알파 0에서는 모든 색이 0이 되어 그 자리의 패킹 바이트가 사라집니다.
마스크 맵
Unity HDRP의 패킹 텍스처. R 메탈릭·G 앰비언트 오클루전·B 디테일 마스크·A 스무스니스.
16비트 입력
받을 수 있으며 샘플마다 상위 바이트를 씁니다. 출력은 항상 8비트입니다.

예시: HDRP 마스크 맵의 텍셀 하나

AO가 200이고 디테일 마스크가 없는, 완전히 거친 금속 텍셀입니다. 스무스니스가 0이라 알파도 0입니다.

원본 텍셀 (crate_MaskMap.png)      R 255   G 200   B 0   A 0
브라우저 캔버스로 읽음             R 0     G 0     B 0   A 0     (미리 곱함: 색 × 0)
랩의 PNG 디코더로 읽음             R 255   G 200   B 0   A 0

Unity HDRP 배치로 저장, A 반전:
  crate_MaskMap-r-metallic.png                 255
  crate_MaskMap-g-ao.png                       200
  crate_MaskMap-b-detail.png                   0
  crate_MaskMap-a-inverted-smoothness.png      255   (255 − 0: 러프니스)

반전한 파일은 배치상의 이름(smoothness) 앞에 inverted-가 붙으므로 내용은 러프니스입니다. 다른 도구가 파일 이름으로 맵을 고른다면 이름을 바꾸세요.

배치별로 채널에 든 것

채널Unity HDRP 마스크 맵glTF 2.0 / Godot ORMUnity URP 채널 패킹
R메탈릭오클루전메탈릭
G앰비언트 오클루전러프니스오클루전
B디테일 마스크(HDRP 전용)메탈릭사용 안 함
A스무스니스 — 반전하면 러프니스사용 안 함스무스니스 — 반전하면 러프니스

내장 Standard 셰이더의 메탈릭 맵은 R(메탈릭)과 A(스무스니스)만 읽습니다. Nerulio의 "Unity URP·내장" 프리셋은 이 문서를 따라 G를 "무시됨"으로 표시하며, Unity URP 문서는 같은 텍스처를 Occlusion에도 지정하면 G에서 오클루전을 읽는다고 적고 있습니다.

이렇게 작동합니다

  • 채널(R·G·B·A)마다 8비트 회색 PNG 하나, 원본과 바이트 동일.
  • 완전히 투명한 텍셀 아래의 RGB 유지(텍셀 2048개로 확인).
  • 고른 엔진 배치(Unity HDRP·URP·ORM)에서의 의미와 함께 채널 미리보기.
  • 채널 반전(예: 러프니스 ↔ 스무스니스) 후 저장.

사용 방법

  1. 패킹된 PNG를 끌어다 놓습니다.
  2. 엔진 배치를 골라 채널마다 의미를 확인합니다.
  3. 필요하면 채널을 반전합니다.
  4. 채널 PNG를 받습니다.

받게 되는 파일

파일용도
crate_MaskMap-r-metallic.png … -a-smoothness.png채널마다 8비트 회색 PNG(색 형식 0) 한 장. 이름은 파일-채널-역할이며, 반전했으면 역할 앞에 inverted-가 붙습니다.
crate_MaskMap-channels.zip네 채널 PNG를 한 압축 파일로(네 채널 모두 저장).

패킹 텍스처를 다른 엔진 배치로 옮기기

예: Unity HDRP 마스크 맵을 Godot 4나 glTF로 옮기는 경우. 엔진 설정은 각 문서를 따른 것이며 Nerulio가 가져오기를 실행하지는 않았습니다.

  1. 패킹된 PNG를 열고 "채널 해석"을 원래 배치(여기서는 Unity HDRP 마스크 맵)로 정합니다. 채널 통계를 보세요. 최소 = 최대인 채널은 상수로 채운 것입니다.
  2. A의 "반전"을 눌러 스무스니스를 러프니스로 바꾼 뒤 "네 채널 모두 저장 (ZIP)"을 누릅니다.
  3. Godot 4에서 개별 맵으로 쓰기: StandardMaterial3D의 텍스처 슬롯에 러프니스·메탈릭·AO PNG를 지정합니다(Ambient Occlusion은 먼저 켭니다). 슬롯마다 *_texture_channel 기본값이 Red라 회색 PNG는 그대로 읽힙니다.
  4. Godot ORMMaterial3D나 glTF: 마스크 패커에서 ORM 프리셋(R 오클루전·G 러프니스·B 메탈릭)으로 AO·러프니스·메탈릭을 다시 패킹합니다.
  5. Unity: 회색 PNG나 다시 패킹한 텍스처는 모두 sRGB (Color Texture)를 끄고 가져옵니다. URP·HDRP에는 러프니스 슬롯이 따로 없으므로 평면을 하나씩 쓰지 말고 메탈릭과 스무스니스를 다시 패킹하세요.

결과 확인

  • 분리할 때와 같은 배치로 평면들을 다시 패킹하고 그 결과를 분리합니다. 채널마다 최소·최대·평균·고유값 개수가 전과 같아야 합니다(랩 측정: 최대 차이 0).
  • 저장한 PNG를 아무 이미지 도구로 엽니다. RGB 복사본이 아니라 원본 해상도의 단일 채널 8비트 회색 이미지여야 합니다.
  • 반전한 평면은 전에 v였던 텍셀이 255 − v여야 합니다(단계 화면에 원본 → 결과가 나란히 보입니다).

문제 해결

증상유력한 원인확인 방법해결
다른 도구에서 텍스처가 투명한 곳마다 채널이 검게 나옴그 도구가 미리 곱한 알파로 파일을 읽음같은 PNG를 채널 단계에서 열면 바이트가 남아 있음랩에서 분리하고, 패킹 데이터는 캔버스를 쓰는 도구에 넣지 않기
파일에 "브라우저 디코딩(바이트 동일 아님)" 표시JPEG·WebP 입력. JPEG 압축은 채널끼리 섞이기도 함파일 목록과 보고서의 exactChannels: false텍스처를 만든 원본 PNG를 분리
분리한 "AO"가 러프니스처럼 보이거나 메탈릭이 지저분함배치를 잘못 고름(G가 HDRP에서는 AO, glTF에서는 러프니스)"채널 해석"을 바꿔 가며 통계와 미리보기 비교텍스처를 내보낸 프로그램의 배치를 고르기
대상 엔진에서 러프니스가 뒤집혀 보임원본 채널이 스무스니스(Unity)였는데 반전하지 않음파일 이름에 inverted-가 없음그 채널의 "반전"을 누르고 다시 저장
16비트 텍스처의 정밀도가 줄어듦출력은 8비트이며 샘플마다 상위 바이트만 남김보고서의 비트 깊이16비트 평면이 필요하면 16비트를 다루는 편집기 사용

다른 방법

방법이럴 때 더 낫습니다
패킹된 채로 쓰기Godot StandardMaterial3D는 맵마다 읽을 채널을 고를 수 있어(roughness_texture_channel·metallic_texture_channel·ao_texture_channel) 순서만 다를 때는 분리할 필요가 없습니다.
이미지 편집기의 채널 분리알파 0 텍셀이 없는 불투명 텍스처를 이미 그 편집기에서 다루고 있을 때. 마스크 맵이라면 투명 영역을 먼저 확인하세요.
러프니스를 스무스니스로Unity용으로 반전한 회색 맵 한 장만 필요할 때.

출력 파일과 검증 방법

"측정 확인"은 내려받은 파일을 페이지 밖에서(Pillow·numpy·별도 파서) 다시 열어 그 속성을 측정했다는 뜻입니다. 게임 엔진에서 불러오는 것은 시험하지 않았습니다.

대상파일검증
Channel PNGs<name>-r/g/b/a.png (8-bit grey)측정 확인 numpy채널마다 바이트가 같고 완전히 투명한 텍셀 아래의 RGB도 유지됩니다.
Normal mapPNG · OpenGL (+Y) or DirectX (−Y)측정 확인 numpy디코딩한 벡터가 단위 길이(최대 오차 0.0002)이고, OpenGL과 DirectX는 초록 채널만 다릅니다.
Packed mask / ORMUnity HDRP mask · URP metallic · ORM (glTF, Godot)측정 확인 Pillow패킹된 바이트 확인: ORM 프리셋, AO 10 / 러프니스 80 / 메탈릭 220 → (10, 80, 220, 255).
Engine importUnity · 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): 무작위 바이트로 된 64×64 ORM을 분리하면 R·G·B·A 모두 최대 차이 0, 알파 0 텍셀 2048개가 모두 RGB 유지(일부러 넣은 (1, 2, 3, 0) 모서리는 R = 1로 복원), 파일은 Pillow에서 모드 L, 64×64로 열림, 반전한 러프니스 평면은 정확히 255 − 러프니스. 배치는 아래 엔진 문서의 것이며(Godot ORM 순서는 엔진 소스), 엔진 가져오기는 하지 않았습니다.

참고한 공식 문서

자주 묻는 질문

이미지 편집기로 열면 안 되나요?

많은 편집기와 모든 브라우저 캔버스는 알파를 미리 곱하므로 투명 텍셀 아래의 메탈릭·러프니스 바이트가 0이 됩니다. 이 경로는 PNG 바이트를 직접 읽습니다.

JPEG도 되나요?

됩니다. 다만 JPEG는 브라우저가 디코딩하며 "바이트 동일 아님"으로 표시합니다.

무료인가요? 계정이 필요한가요?

이 페이지의 기능은 모두 무료이며 계정 없이 쓸 수 있습니다. 워터마크나 막혀 있는 내보내기가 없습니다.

스프라이트가 업로드되나요?

아니요. Studio는 이 브라우저 탭 안에서 디코딩·패킹·내보내기를 합니다. 프로젝트는 브라우저(IndexedDB)에 자동 저장되며 .nerulio 파일로 저장할 수 있습니다.

Aseprite나 엔진 플러그인을 설치해야 하나요?

아니요. .aseprite 파일은 브라우저에서 읽고 씁니다. 엔진별 번들에는 그 엔진에 필요한 것이 들어 있습니다(Godot는 가져오기 설정과 씬, Unity와 Godot 타일셋은 작은 편집기 스크립트).