같은 텍스처인데 왜 게임 엔진에서는 다르게 보일까? - sRGB와 Linear 이야기
Substance Painter나 Photoshop에서 꽤 괜찮게 만들어 놓은 텍스처가 게임 엔진에 넣는 순간 이상하게 보일 때가 있다.
색이 너무 밝아지기도 하고, 반대로 탁해지기도 한다.
특히 Roughness나 Metallic 같은 맵이 이상하게 동작하기 시작하면 처음에는 셰이더 문제인가 싶어진다.
그런데 이런 문제 중 상당수는 sRGB와 Linear 설정에서 시작한다.
우선 아주 간단하게 생각해 보자
게임에서 사용하는 텍스처를 크게 두 종류로 나누면 이해하기 쉽다.
사람이 직접 보는 색
예를 들면
- Base Color
- Albedo
- Diffuse
같은 텍스처다.
이런 맵은 실제로 화면에서 우리가 보는 '색'을 표현하기 때문에 보통 sRGB로 처리한다.
계산에 사용하는 데이터
반면
- Roughness
- Metallic
- AO
- Mask
- Height
같은 텍스처는 조금 다르다.
이것들은 색이라기보다는 0에서 1 사이의 숫자를 저장해 놓은 데이터에 가깝다.
그래서 일반적으로 Linear 데이터로 읽어야 한다.
Roughness에 sRGB가 적용되면 어떻게 될까?
예를 들어 Roughness 값이 0.5라고 해보자.
우리는 셰이더에서 그대로 0.5라는 값이 들어가기를 기대한다.
그런데 이 텍스처에 sRGB 변환이 적용되면 엔진이 값을 색 데이터로 해석하면서 변환을 거친다.
그러면 원래 의도했던 0.5와 다른 값이 셰이더에 전달될 수 있다.
결과적으로
“섭스턴스에서는 적당히 거칠었는데 엔진에서는 왜 이렇게 번들거리지?”
같은 일이 생긴다.
이때 Roughness를 다시 칠하기 시작하면 문제 해결 방향이 완전히 잘못된 것이다.
Base Color는 반대로 sRGB가 중요하다
그렇다고 모든 텍스처에서 sRGB를 꺼버리면 되는 것도 아니다.
Base Color 같은 색상 텍스처는 일반적으로 sRGB 상태로 사용하는 것이 맞다.
사람의 눈은 빛의 밝기를 선형적으로 느끼지 않는다.
그래서 우리가 일반적인 이미지에서 사용하는 색 정보에는 감마 보정이 들어가 있고, 게임 엔진은 이것을 Linear 공간으로 변환한 뒤 라이팅 계산을 한다.
따라서 컬러 텍스처는
sRGB → Linear 변환 → 라이팅 계산
과정을 거치는 것이 정상적인 흐름이다.
가장 많이 실수하는 것이 Packed Texture다
요즘은 텍스처 메모리를 줄이기 위해 여러 맵을 하나의 RGB 채널에 넣는 경우가 많다.
예를 들면
- R = Ambient Occlusion
- G = Roughness
- B = Metallic
같은 방식이다.
Unreal의 ORM이나 ARM 텍스처가 대표적이다.
이 텍스처들은 세 채널 모두 색이 아니라 데이터다.
따라서 이런 Packed Texture에 sRGB가 켜져 있으면 문제가 생길 가능성이 높다.
엔진에 넣은 뒤 가장 먼저 확인할 부분 중 하나다.
노멀맵은 또 별개의 문제다
Normal Map 역시 색처럼 보이지만 실제로는 방향 벡터를 저장한 데이터다.
그래서 일반적인 컬러 텍스처처럼 취급하면 안 된다.
다행히 Unity나 Unreal에서는 Normal Map으로 지정하면 필요한 처리를 엔진에서 알아서 해주는 편이다.
그래서 노멀맵을 Import했는데 뭔가 이상하다면 먼저 Texture Type이나 Compression 설정이 정상적으로 Normal Map으로 되어 있는지 확인하는 것이 좋다.
Substance Painter와 게임 엔진 화면이 다른 이유
이 부분에서 많이 혼란스러워진다.
Substance Painter 화면과 Unity 또는 Unreal 화면이 완전히 똑같을 거라고 생각하기 쉽다.
하지만 실제로는
- HDRI
- Exposure
- Tone Mapping
- Color Management
- Reflection
- Post Process
등의 환경이 서로 다르다.
따라서 어느 정도 차이가 나는 것은 당연하다.
다만 차이가 지나치게 크다면 그때는 먼저 텍스처의 Color Space 설정부터 확인하는 편이 좋다.
실무에서는 이렇게 구분하면 편하다
아주 단순하게 기억하면 된다.
색이면 sRGB.
숫자 데이터면 Linear.
물론 특수한 셰이더나 파이프라인에서는 예외도 있지만 일반적인 PBR 작업에서는 이 기준만 기억해도 상당수의 문제를 피할 수 있다.
특히 Roughness, Metallic, AO를 작업할 때는 이것들이 '그레이스케일 이미지'가 아니라 실제로는 셰이더에 전달되는 데이터라는 개념을 가지고 있는 것이 중요하다.
결국 텍스처도 이미지가 아니라 데이터다
게임 그래픽 작업을 처음 할 때는 텍스처를 전부 그림처럼 생각하기 쉽다.
하지만 PBR 작업으로 들어가면 조금 관점이 달라진다.
Base Color는 색을 저장하지만 Roughness는 표면의 거칠기를 저장하고, Metallic은 재질의 성질을 저장하며, Normal Map은 표면 방향을 저장한다.
결국 같은 PNG나 TGA 파일이라도 안에 들어 있는 정보의 의미가 전혀 다른 것이다.
그래서 텍스처가 엔진에서 이상하게 보일 때는 무조건 다시 그리기 전에 한 번 생각해 볼 필요가 있다.
“이 텍스처는 색인가, 데이터인가?”
이 질문 하나만으로도 의외로 많은 문제가 해결된다.
'게임관련 > 게임그래픽관련' 카테고리의 다른 글
| 모델링할 땐 괜찮았는데 게임에 넣으면 왜 작아 보일까? (0) | 2026.08.20 |
|---|---|
| 노멀맵은 강할수록 좋은 게 아니다 — 디테일을 망치는 노멀의 함정 (0) | 2026.08.17 |
| 게임 그래픽은 언제부터 '좋은 그래픽'이 아니게 되는가 (0) | 2026.08.12 |
| 2026년에 나는 왜 세가 새턴 게임을 다시 하고 있을까 (0) | 2026.08.11 |
| [TIP] 3DSMAX의 Command Panel을 Float 하기 (0) | 2016.10.11 |










