본문 바로가기

유니티/그래픽스

[Unity] 감마와 리니어 색 공간 (Gamma & Linear)

반응형

베버의 법칙

감마 공간과 리니어 공간의 차이점을 알기 위해서는 베버의 법칙에 대해 먼저 알아야 한다.

두 영역의 차이가 베버의 법칙에서 기인하기 때문이다.

 

그렇다면 베버의 법칙이란 뭘까?

 

베버의 법칙이란 감각기에서 자극의 변화를 느끼기 위해서는 처음 자극에 대해 일정 비율 이상으로 자극을 받아야 된다는 이론을 말한다.

이론에서 알 수 있듯이 이 법칙은 인간의 색깔 인지뿐만 아니라 감각기를 통해 받아들이는 모든 감각에 해당한다.

 

예를 들면, 우리의 미각은 쓴 커피를 마시고 비스킷의 단맛을 쉽게 느끼지만 청포도 에이드를 마실 때는 비스킷의 단맛을 알아차리기 쉽지 않다.

또한 몸의 어딘가에 외상을 입었을 때 본인도 모르게 다른 상처가 나있는 경우가 많은데, 이 역시 큰 고통에 의해 작은 고통이 무뎌지기 때문이다. 반면 일상에서의 작은 촉각(통각)은 쉽게 알아차린다.

시각 역시 베버의 법칙을 따른다. 어두운 장소에서 촛불 하나가 켜진 상황은 아주 쉽게 알아차리지만, 촛불이 100개 켜진 상황에서 1개가 더 켜진 경우는 알아차리기 어렵다.

 

위 상황을 유니티에서 시뮬레이션하여 확인하면 다음과 같다.

포인트 라이트 1개 포인트 라이트 2개

기존 라이트 1개 대비 100%만큼 증가한 경우

 

포인트 라이트 14개 포인트 라이트 15개

기존 라이트 14개 대비 7% 증가한 경우

 

포인트 라이트가 1개에서 2개로 변화한 경우 우리는 밝기가 변화했다는 것을 쉽게 알 수 있다.

그러나 포인트 라이트가 14개에서 1개가 증가하여 15개가 된 경우, 우리는 밝기의 변화를 단번에 알아차리기 힘들다.

 

위의 테스트로 알 수 있듯이 절대적인 숫자의 차이가 아닌 상대적인 비율을 통해 우리 감각기관이 인지한다.

그리고 이렇게 색변화를 인간이 인지하기 쉽게 변환해 놓은 색 공간감마 공간이라고 한다.

반면 보정되지 않은 순수한 색상 공간리니어 공간이라고 한다.


그래픽스에서의 베버의 법칙 이용

이러한 베버의 법칙을 적극적으로 활용하는 것 중 하나가 모니터이다.

모니터는 출력되는 그래픽을 인간이 인지하기 쉬운 색상으로 변환하여 보여준다.

모니터는 감마 공간을 우리에게 보여주는 것이다.

 

게임 엔진에서의 그래픽 처리 역시 베버의 법칙을 따른다.

그래서 유니티에서 빌트인 파이프라인으로 제작하면 기본적으로 감마 스페이스로 제작이 된다.

그런데 URP 혹은 HDRP 같은 SRP으로 프로젝트를 제작하면 감마가 아닌 리니어 컬러 스페이스가 기본으로 실행된다. (변경가능)

 

우리의 눈에 익숙한 감마 색 공간으로 통일하면 될 텐데 왜 번거롭게 두 개의 영역으로 나누어둔 것일까?


두 색 공간의 차이

문제는 감마 컬러 스페이스가 여러 가지 단점을 갖고 있다는 것에 있다.

 

감마 색 공간은 리니어 공간의 각 값에 2.2를 제곱하여 얻어진다. 그런데 이 과정에서 색의 분포가 크게 변경되고, 이는 채도 문제로 이어지게 된다.

출처 : OpenGL

위의 이미지를 보면 감마 보정을 하면서 그래프가 휘어진다. 휘어진 만큼 색상들이(원래는 서로 다른 색상이었을지라도) 비슷해지게 되는 것이다.

 

또한 감마 공간은 밝기가 변경되는 문제가 발생한다.

이는 텍스쳐가 sRGB로 저장되기 때문에 발생하는 문제이다.

위에서 언급한 것처럼 모니터는 감마 보정을 자동으로 한다. 그러나 우리가 컴퓨터에 저장하는 사진과 같은 텍스쳐는 반드시 리니어 공간이어야만 한다(당연한 얘기지만 사진의 색상 그 자체를 유지해야 한다).

따라서 컴퓨터에 저장하는 텍스쳐는 모니터가 감마 보정할 것을 예상하여 역으로 인코딩을 한다. 그래야 모니터에서 디코드를 했을 때 리니어한 색상이 나오기 때문이다.

이렇게 미리 감마 인코딩 되어 색상을 저장하는 방식을 sRGB라고 한다.

 

문제는 이 sRGB 텍스쳐가 엔진에서 디코드 되며 밝기마저 변화시킬 수 있는 것이다.

만약 두 개 이상의 텍스쳐가 합쳐져 있다고 하자.

출처 : 유니티

이 경우 원본 이미지(sRGB)를 합쳐서 1이 넘어가는 영역에 대해 모두 하얀색으로 처리를 한 다음 다시 감마 색 공간으로 변환시키기 때문에 색의 밝기가 바뀌게 된다.

 

아래의 이미지가 채도와 밝기 모두 원본과 비교하여 과도하게 변경된 것을 알 수 있다.

 

따라서 우리 눈에 익숙한 색 공간은 감마 컬러 스페이스지만 몇 개의 이유 때문에 리니어 공간이 엔진에서는 적합하다.

 

그런데 또 의문이 들 수 있다.

리니어 색 공간이 좋다면 컬러 스페이스를 리니어로 고정시키지 않고 왜 감마 스페이스를 별도로 추가해 둔 것일까?

 

그 이유는 사실 간단하다.

몇 개의 하드웨어가 리니어 색 공간을 지원하지 않기 때문이다.

따라서 저사양의 몇몇 디바이스를 지원하기 위해 감마 스페이스는 아직도 존재한다.


유니티에서의 감마 공간과 리니어 공간

감마공간과 리니어 공간을 변경하려면 다음과 같이 수동으로 바꿔줘야 한다.

ProjectSettings / Player / OtherSettings / Rendering / Color Space

하지만 두 색 공간의 차이점을 비교하기 위해서 셰이더를 사용해 비교해 보았다.

 

먼저 보정이 들어가지 않은 리니어 색 공간은 다음과 같이 제작할 수 있다.

리니어 공간

 

반면 감마 보정이 들어간 감마 컬러 스페이스는 다음과 같이 셰이더로 제작이 가능하다.

감마 공간

감마 스페이스는 리니어 컬러 스페이스에 2.2를 제곱한 것과 같기 때문에 Power(2.2)를 해준다.

 

최종적으로 이 둘을 비교하면 다음과 같다.

리니어 스페이스(좌) 감마 스페이스(우)

확실히 감마 공간이 리니어에 비해 안정감 있고 순차적으로 보인다. 하지만 실제로 고른 그레이 스케일은 왼쪽인 리니어 컬러 스페이스이다.

 

이제 감마 컬러 스페이스가 실제로 어떻게 색이 분포되어 있는지 확인해 보자.

감마 컬러 스페이스

제일 오른쪽 이미지를 보면 검은색이 아주 조밀하게 밀집되어 있고 하얀색이 넓게 분포되어 있는 것을 알 수 있다.

 

원본 이미지의 색상에 2.2를 제곱하기 때문에 색상의 분포가 변화하게 되고, 이 때문에 나타낼 수 있는 색의 분포가 변화한다. 다시 말해, 색상의 채도가 변화하는 것이다.

 

 

반응형