툴/유니티

Gamma Correction과 Linear Rendering

스튜디오 오버그래픽스 2023. 6. 2. 20:26

https://youtu.be/Xwlm5V-bnBc

https://youtu.be/oVyqLhVrjhY

https://youtu.be/lUvsEfqOkUo

위 3개 영상을 참고한 내용 정리

 

Gamma Correction, Linear Workflow, Gamma Workflow, sRGB 등은 디지털 이미지를 저장하는 포맷과 출력하는 모니터와 사람 눈이 색을 인식하는 영역에 있어서 필요한 여러 개념들.

또한 셰이더를 다루는데 있어서 알아두어야할 개념.


URP의 기본이 Linear Workflow가 되면서 중요해졌음.(감마에서 리니어로 변한 추세)

예전 모바일은 리니어를 지원 안하고, 유니티 레거시의 기본이 감마였음.

 

감마보정

베버의 법칙 : 변화량이 많은 상황에서 자극을 크게 받아들임

ex) 어두운 방에 촛불을 킬때는 변화가 큼(자극이 큼), 이미 밝은 방에서 촛불을 킬때는 변화가 적음(자극이 적음)

 

위 2가지 흑백 그라데이션을 보면 1번(위) 그라데이션이 검정에서 흰색으로 자연스럽게 넘어가는 그라데이션 같음.

2번(아래)그라데이션은 검정에서 급진적으로 회색이 됐다가 천천히 흰색이 되는 그라데이션 같음.

즉, 눈으로 보면 1번이 자연스러운 그라데이션 같아보임.

동그라미친 중간영역의 색중에 1번의 값이 흑백 50%(128,128,128)의 중간 회색일거 같음.

그러나 2번의 동그라미 값이 흑백50%(128,128,128)의 중간 회색임.

 

그러면 왜 2번 중간 영역을 흑백50%의 중간 회색보다 더 밝은 값이라고 느꼈을까?

왼쪽의 어두운 부분에서 변화량을 더 크게(자극이 크게)느꼈고 급진적으로 변화했다고 판단을 했음.

또한 왼쪽 어두운 부분에서는 밴디현상이 보이고, 오른쪽 밝은 부분에서는 밴딩 현상이 보이지 않음.

사람의 눈은 어두운 부분에 더 민감함.

 

그래서 모니터는 어두운 곳에 민감한 인간의 감각에 맞춰 어두운 부분의 밀도를 올림.

 

1번은 이미지를 감마 보정한 결과물임. 그래서 1번이 자연스러운 그라데이션 처럼 보임.

 

1대1 형태로 대입되는 직선 형태의 입출력 값을 제곱해서 보정해줌.(결과값이 더 어두워짐)

 

모니터에서 어둡게 출력하는 이유?

어두운 부분에서 유독 밴딩현상이 뚜렷하게 보이는데 전체적으로 어두워지면 그라데이션을 자연스러운 형태로 인식하게 되고 밴딩현상의 분포도 균일해보임.

 

그러나 찍었던 사진을 모니터에서 볼때 어두워졌다고 못느끼는 이유?

어두워질것을 감안해서 컴퓨터에 저장할때는 밝게 보정해서 저장하기 때문(sRGB 색공간)

 

굳이 이미지를 밝게 저장하고, 모니터에서는 어둡게 출력될 필요가 있나?

밝게보정되고 다시 어둡게 보정되면서 결과적으로 어두운 부분의 영역이 조밀해지게됌.

 


 

감마(Gamma) 파이프라인에서의 ADD 이펙트

레거시에서는 구형 디바이스나 호환성 때문에 Color Space Gamma가 기본값이었음.

이미지는 sRGB색공간에 밝게 저장되어 있는 상태인데 만약 이 이미지 2개가 ADD되는 이펙트라면,

이미 밝게 보정된 상태에서 두 이미지의 컬러가 더해지는 연산이 이루어지면서 너무 밝아서 색이 뭉개지는 부분이 생겨버리고, 모니터에서 출력될때 다시 어둡게 출력된다고 해도 원치 않는 결과물이 나옴.

 

대략적인 예시 ex)

컬러 값을 유니티에서 처럼 (0~1)사이라고 했을때

이미지 원본 (0.5,0.5,0.5) => sRGB 밝게 저장된 이미지 (0.6,0.6,0.6)

sRGB 이미지 2장 additive => (1.2, 1.2, 1.2) => 그러나 1이상은 표현이 안됌(1.0 , 1.0 , 1.0)

감마 보정은 제곱한 그래프의 형태기 때문에 0,1의 값은 변화가 없고 0~1사이의 중간 값만 변화가 있음.

즉, 1값은 감마 보정해도 1

결국 너무 밝아져서 1.0이 넘어간 부분은 디테일한 컬러를 표현 못하고 다 흰색으로 뭉개져서 그려짐.

 

선형(Linear) 파이프라인에서의 ADD 이펙트

감마 파이프라인에서 처럼 이미지는 일단 밝게 sRGB 저장됌.

그러나 연산할때 밝게 저장된 상태에서 연산하지 않고 Linear상태에서 연산하고,

연산 결과는 다시 sRGB 밝게 저장, 그리고 출력할때 어둡게 나옴.

 

이펙트 연산 단계

1. 이미지는 하드에서는 sRGB 색공간에서 밝게 저장됌

2. 컬러 ADD 연산할때는 이미지 원본컬러상태(Linear)에서 연산함

3. 컬러 ADD 연산한 결과값은 sRGB 색공간에 다시 밝게 저장됌

4. 모니터에서 출력할때는 다시 어둡게 출력됌.

 

결과적으로 연산할때 Linear상태(원본컬러)에서 연산하기 때문에 감마 파이프라인에서 보다 정확한 결과값.

 


조명에서의 감마와 선형 파이프라인

 

같은 조명,환경,각도에서 캡처한 화면

 

Gamma는 어두운 영역이 더 많고 점진적인 색 변화가 있음.

Gamma가 더 우리 눈에는 자연스러운 그라데이션 같음.

 

Linear는 어두운영역이 덜하고 급격한 색변화가 있음.

Linear가 우리 눈에는 부자연스러운 그라데이션 같음.

 

조명 값을 내적하면 Cos값과 같기 때문에 조명을 가장 많이 받는 부분은 1이고 가장 적게 받는 부분은 0이다.

그리고 중간값은 0.5가 아니고 Cos의 90도값인 0.707..이 중간값임.

조명을 연산하는 내적값은 Cos이기 때문에 곡선 형태의 변화량이 나타남

곡선 형태의 변화량을 보여주는건 Linear.

균일한 그라데이션이 나오지 않고 급진적이며 흰색이 더 많은게 옳은 결과값.

즉, Gamma보다는 Linear가 실사 조명표현에 더 가까움.

 

텍스쳐는 sRGB로 저장되어 있고, 조명 연산은 Linear로 저장되어 있음.

선형 파이프라인에서는 조명을 선형으로 계산하고 sRGB로 밝게하고서 출력함.

감마 파이프라인에서는 조명을 선형으로 계산하고 그대로 출력함.

 

감마 파이프라인에서는 조명을 선형 계산하는데 텍스쳐는 감마 계산해서 문제가 복잡해짐.

선형 파이프라인에서는 조명도,텍스쳐도 선형 계산하기때문에 계산이 정확함.

 

결론은 조명 연산도 Linear에서 하면 정확해짐

 


선형 파이프라인에서의 데이터 이미지 연산

 

보여질 용도의 텍스쳐(눈에 원하는 느낌대로 보이는게 중요함)

-Albedo, Emission 등 주로 컬러

 

표현을 위한 데이터 텍스쳐(정확한 수치값이 중요함)

-Normal, Height, Metalic 등 Masking용도로 사용하는 텍스쳐, 주로 흑백채널

 

흑백 채널을 이용한 UV 이동 ex)

흑백 텍스쳐의 채널 R값(0~1)을 UV좌표에 대입해서 이동 시키려고함.

포토샵에서 흑백 텍스쳐(128,128,128)를 중간 회색값으로 만들고

흑백 텍스쳐의 R채널 값만큼 UV 좌표를 이동 시키면 0.5만큼 이동할수 있을거라고 생각함.

감마 파이프라인에서는 0.5만큼 잘 이동함.

선형 파이프라인에서는 0.5보다 덜 이동함.(0.5 -> 0.218)

=>선형 파이프라인에서는 sRGB로 밝게 저장된것을 다시 어둡게 Linear상태에서 연산하기 때문.

 

이미지 텍스쳐는 Linear상태에서의 연산이 옳지만

데이터 텍스쳐는 sRGB상태에서의 연산이 옳음

 

이미지 텍스쳐는 sRGB 옵션 체크, 데이터 텍스쳐는 sRGB 옵션 체크 해제

 


sRGB/Linear 사용

 

 

 

금속을 표현하는 머테리얼이 있다고 했을때

Albedo는 sRGB체크, Metalic, Normal, Height 등은 sRGB 체크 해제

source의 Metallic Alpha로 선택되어 있으면 Metallic텍스쳐의 알파값을 Smoothness로 사용하는 것.

 

 

만약 전체가 금속인 재질이면 따로 Metalic텍스쳐가 필요 없음. 그냥 Metallic을 1로 설정.

그러면 Metallic Alpha를 사용하지 못하므로 source에서 Albedo Alpha를 선택하면 알베도의 알파값을 Smoothness로 사용.

 

 

*Albedo는 보여질 텍스쳐라서 sRGB를 체크했지만 이제 Albedo의 알파값은 데이터 텍스쳐로서 사용되는 상태.

*데이터 텍스쳐로서는 sRGB가 체크되면 정확한 연산이 어려워짐.

그러나 sRGB 옵션이 체크되도 알파채널은 Linear임(sRGBA가 아닌 sRGB인 이유)

 

 

데이터 텍스쳐의 sRGB체크 차이

  • Metallic : 일반적으로 금속 or 비금속을 0과 1로 표현하는데 sRGB가 체크 해제되어서 감마 보정이 들어가도 감마보정은 제곱식이라서 0과 1의 값은 보정해도 차이가 없음. 결국 메탈릭은 0~1사이 중간값이 변해도 영향이 없기 때문에 sRGB옵션 체크 유무에 따른 영향이 없음.
  • Normal : 노멀맵으로 텍스쳐 타입을 설명하면 알아서 sRGB체크 해제된 상태로 적용됌.
  • Occlusion(G채널 사용) : 오클루전은 정확도 좀 떨어져도 크게 특이점이 보이진 않음.

데이터 텍스쳐에 sRGB체크를 실수해도 큰 차이는 없을 수 있음.

(흔한 경우는 아니지만 커스텀 셰이더로 채널을 직접 지정하고 변형해서 쓰다보면 문제가 될 경우는 있음)

 

 

Shader Graph의 감마 보정과 컬러

 

쉐이더 그래프에서 만든 Color(0.5, 0.5, 0.5)를 Base Color에 넣은 결과와

float 0.5를 Base Color에 넣은 결과는 다름

 

값을 add 해보면 차이가 남.

color(0.5)는 add해도 1이 안됌

float(0.5)는 add하면 1이됌.

 

쉐이더 그래프에서 Color는 이미 밝아진 상태의 값을 보여줌.

쉐이더 그래프에서는 0.5의 값으로 보여지지만 내부적으로는 0.5보다 낮은 값.

 

 

Colorspace Conversion노드를 통해서 Linear를 RGB로 바꿔주면 우리 눈에 보이던 0.5의 값을 받아옴.

add해보면 흰색(1의값)이 나오는 걸 볼수 있음.

 

 

 

색을 어둡게하는 감마 보정이 2.2 제곱한 값이기 때문에 역으로 0.45를 제곱해도 

Colorspace Conversion(Linear->RGB)한 값과 같은 값이 나옴.