ORM 채널 패킹: AO·Roughness·Metallic을 한 장에 합치는 순서
흑백 AO, Roughness, Metallic 맵을 하나씩 연결하던 재질은 한 장으로 줄일 수 있습니다. 그런데 ORM 텍스처를 만들고도 Unity나 Unreal에서 재질이 다르게 보이면, 맵 값이 틀린 것인지 채널을 다른 순서로 읽는 것인지 구분하기 어렵습니다. 세 맵을 어느 채널에 넣고 엔진에서는 어떻게 읽어야 할까요?
1. ORM 텍스처 채널 패킹 도구
AO, Roughness, Metallic 맵을 각각 선택하세요. 세 파일은 픽셀 크기가 같아야 합니다. 도구가 크기를 바꾸면 데이터 위치가 어긋날 수 있어 자동 리사이즈하지 않습니다.
각 칸에 같은 해상도의 grayscale 맵을 선택하세요. 파일은 이 브라우저 안에서만 처리하며 서버로 전송하지 않습니다. PNG를 권장하며 입력 이미지의 알파 채널은 사용하지 않습니다.
맵 세 장을 선택하고 패킹 버튼을 누르세요.
ORM.png 다운로드합쳐진 RGB 미리보기
이 도구는 각 입력 이미지가 브라우저에서 디코딩한 픽셀의 R 값을 읽어 출력 채널에 복사합니다. AO의 R은 출력 R, Roughness의 R은 출력 G, Metallic의 R은 출력 B가 됩니다. 출력 알파는 모든 픽셀에서 255로 고정합니다.
| 입력 맵 | 출력 채널 | 픽셀 계산 |
|---|---|---|
| AO | R | R_out = AO_R |
| Roughness | G | G_out = Roughness_R |
| Metallic | B | B_out = Metallic_R |
| 알파 | A | A_out = 255 |
예를 들어 한 픽셀에서 AO가 128, Roughness가 64, Metallic이 255라면 저장되는 값은 RGBA (128, 64, 255, 255)입니다. 밝기 평균이나 색 보정은 하지 않습니다. grayscale 이미지의 픽셀 값을 그대로 옮깁니다.
브라우저가 읽을 수 있는 PNG, WebP, JPEG를 선택할 수 있지만, 압축 손실을 피하려면 grayscale PNG를 권합니다. 입력 알파 채널은 사용하지 않습니다. 결과는 브라우저의 Canvas에서 만들고 서버로 보내지 않습니다. Canvas 출력은 채널당 8비트이므로 16비트 PNG나 EXR의 값을 보존하는 용도로 쓰지 마세요.
2. ORM 텍스처 채널 순서는 어디서 정했나
R, G, B는 이미지 파일의 칸이고 Ambient Occlusion, Roughness, Metallic은 셰이더가 읽는 값입니다. 같은 이미지라도 어느 칸을 어떤 입력에 연결하느냐에 따라 결과가 달라집니다. ORM이라는 이름만 보고 엔진이 자동으로 순서를 맞춰 준다고 가정하면 안 됩니다.
glTF 2.0은 R=AO, G=Roughness, B=Metallic
glTF 2.0에서 Metallic-Roughness 텍스처의 G는 Roughness, B는 Metallic 값입니다. Occlusion 텍스처는 R에서 값을 읽습니다. 두 속성이 같은 이미지 텍스처를 참조하도록 만들면 익숙한 ORM 순서인 R=AO, G=Roughness, B=Metallic이 됩니다. 알파 채널은 이 세 값에 쓰지 않아도 됩니다.
이 도구의 출력은 이 순서를 따릅니다. 따라서 결과는 glTF 기준 ORM 텍스처입니다. glTF에서 텍스처를 연결할 때는 Metallic-Roughness와 Occlusion 속성이 같은 이미지를 참조하는지 확인하세요. 값은 컬러가 아니라 재질 데이터이므로 선형으로 읽어야 합니다.
Unreal Engine은 채널을 머티리얼에 직접 연결
Unreal Engine의 Texture Sample에서 R을 Ambient Occlusion, G를 Roughness, B를 Metallic 입력에 연결하면 이 글의 ORM 순서로 사용할 수 있습니다. 텍스처 에셋에서는 sRGB를 끄세요. 이미 만든 Texture Sample의 Sampler Type이 Color라면 Linear Color로 바꾸고 머티리얼을 다시 컴파일합니다.
Epic 공식 Texture Masks 예시도 채널 패킹을 보여 주지만, 예시에서는 R을 Ambient Occlusion, G를 Metallic Mask, B를 Non-Metallic Mask로 씁니다. 즉, 모든 Unreal 텍스처가 같은 채널 순서를 따르는 것은 아닙니다. 다른 사람이 만든 텍스처라면 맵 이름과 머티리얼 연결부터 확인하세요.
Unity 6 URP는 기본 packed 순서가 다름
Unity 6.5 (6000.5) URP Lit과 Complex Lit의 공식 packed texture 규칙은 R=Metallic, G=Occlusion, B=미사용, A=Smoothness입니다. 이 도구의 ORM PNG를 그 슬롯에 그대로 넣으면 AO를 Metallic으로 읽고, 알파 255를 Smoothness 1로 읽을 수 있습니다. 이 출력은 Unity URP 기본 packed 텍스처와 같은 파일이 아닙니다.
Unity URP 기본 규격으로 다시 패킹하려면 ORM의 B를 새 R(Metallic), ORM의 R을 새 G(Occlusion), 255에서 ORM의 G를 뺀 값을 새 A(Smoothness)에 넣어야 합니다. Shader Graph에서 ORM을 직접 읽는 구성이라면 B를 Metallic, R을 Occlusion에 연결하고 Smoothness에는 1−G를 사용합니다. 이 안내는 Unity 6.5 (6000.5) URP Lit/Complex Lit 기준이며 Built-in Render Pipeline이나 HDRP 규칙으로 넓혀 적용하지 않습니다.
3. ORM 텍스처를 불러오기 전에 sRGB 확인
ORM은 화면에 예쁘게 보이도록 만든 컬러 이미지가 아니라 셰이더 입력값을 담은 데이터 이미지입니다. Unreal과 Unity URP에서는 해당 텍스처의 sRGB를 끄고, glTF의 Metallic-Roughness 값은 선형으로 읽습니다. 컬러 텍스처와 데이터 텍스처의 sRGB 설정은 같지 않습니다.
Roughness와 Metallic을 Raw로 읽어야 하는 이유는 Roughness·Metallic Map의 Raw 설정 글에서 이어서 볼 수 있습니다. Normal Map도 색이 아니라 방향 데이터이므로 sRGB로 읽었을 때의 차이를 따로 확인하세요.
반대로 Base Color나 Albedo는 색 정보를 담습니다. ORM 텍스처에 컬러 맵 설정을 그대로 적용하면 안 됩니다. 컬러 맵과 데이터 맵의 구분은 PBR Albedo의 값 범위 글을 참고하세요. Unity에서 Color Space와 sRGB가 어떻게 나뉘는지는 Unity 색관리 글에서 이어서 볼 수 있습니다.
마지막 확인: ORM 텍스처 채널과 읽는 방식
세 장을 한 파일로 합치는 계산은 단순합니다. AO의 grayscale 값은 R, Roughness는 G, Metallic은 B에 복사하고 알파는 255로 채웁니다. 하지만 결과를 바르게 읽으려면 사용 중인 포맷과 셰이더의 슬롯 규칙을 따라야 합니다.
ORM 채널 순서는 파일 이름이 아니라 포맷과 머티리얼 연결이 정합니다. glTF 순서와 Unity URP 기본 packed 순서를 구분하고, 데이터 텍스처의 sRGB 설정을 마지막으로 확인하세요.
공식 문서
채널과 색공간 설정은 엔진 버전에 따라 달라질 수 있습니다. 아래 문서는 이 글에서 비교한 공식 기준입니다.
vfx 잡학지식

댓글 0
첫 댓글을 남겨보세요.