검정과 흰색의 정확한 중간은 128일까?
8비트 이미지에서 128은 당연한 중간처럼 보인다. 하지만 sRGB 값은 직접적인 빛의 측정이 아니라 인코딩된 지시다. 지시를 평균하는 것과 그 지시가 뜻하는 빛을 평균하는 것은 다를 수 있다. 페이드, 투명 경계, 이미지 크기 변경에 중요한 차이다.
코드값의 절반은 빛의 절반이 아니다.
숫자 안의 유용한 곡선
sRGB는 비선형 전달 함수로 선형광을 저장값으로 바꾼다. 검정 근처에는 짧은 선형 구간이 있고 나머지는 거듭제곱 모양의 곡선을 따른다. 범위 안에서 수치 정밀도를 다르게 배분하는 방식이다. 흔히 감마 문제라고 하지만 정확한 sRGB 함수는 하나의 단순 거듭제곱이 아니다.
여기서 선형광은 0을 검정, 1을 모델의 기준 흰색으로 정규화했다. 화면의 물리적 밝기를 지정하지는 않는다. 0.5는 기준 선형광 성분의 절반이지 보편적인 제곱미터당 칸델라 값이 아니다.

서로 다른 두 중간
검정 픽셀과 흰 픽셀의 인코딩값을 평균하면 0.5다. 이를 sRGB 함수로 디코딩하면 선형광은 약 0.214다. 저장 숫자가 양끝의 가운데에 있어도 기준 빛의 약 21.4퍼센트만 나타내는 셈이다.
반대로 양끝을 디코딩하고 선형값을 평균한 다음 다시 인코딩해 보자. 빛의 절반은 sRGB 약 0.735, 8비트로는 약 188이 된다. 둘 다 중간값이지만 서로 다른 공간의 중간이다. 여기서 말하는 같은 양의 빛 혼합에 해당하는 것은 후자다.
그라데이션이 선택을 보여 준다
두 띠는 검정과 흰색 끝점이 같다. 인코딩값 그라데이션은 저장 숫자를 같은 간격으로 바꾼다. 선형광 그라데이션은 빛의 기여를 같은 간격으로 바꾼 뒤 인코딩한다. 일반적으로 sRGB를 해석하는 화면에서는 두 번째 띠의 중간이 더 밝다.
어느 쪽도 지각적으로 같은 간격을 보장하지 않는다. 밝기에 대한 판단은 맥락과 적응에 영향을 받으며 지각 색 공간은 다른 목적을 다룬다. 빛을 섞으려는 연산에는 선형광이 적절하다. 시각적으로 고른 팔레트를 원하는 디자이너는 다른 공간을 의도적으로 고를 수 있다.

색에서도 같은 문제가 생긴다
빨강과 초록의 인코딩값을 바로 평균하면 (0.5, 0.5, 0)이다. 선형 성분을 평균하고 인코딩하면 약 (0.735, 0.735, 0)이 된다. 각 채널이 표시 인코딩 전에 의도한 빛의 기여를 유지하므로 두 번째 혼합이 밝다.
물감을 섞는 과정을 재현하지는 않는다. 안료는 조명 스펙트럼 일부를 흡수하고 산란시키므로 감산 혼합은 물리가 다르다. 세 숫자만으로 실제 스펙트럼 분포를 모두 식별할 수도 없다. sRGB를 가정한 가산 RGB 예제이며 특정 모니터의 원색이나 보정 상태를 평가하지 않는다.

투명한 경계도 같은 계산을 물려받는다
흰 모양이 검은 배경 위 반 픽셀을 덮는다고 하자. 점유율을 빛의 혼합 가중치로 해석하면 선형 합성 결과는 흰 빛의 절반이다. 인코딩 중간값을 답으로 쓰면 경계가 어두워진다. 축소 시 여러 픽셀을 평균하거나 레이어를 섞을 때도 비슷한 문제가 생긴다.
실제 소프트웨어는 작업 색 공간, 알파 표현, 출력 변환을 명시적 또는 암묵적으로 선택한다. RGB라는 표시만으로는 이를 모두 알 수 없다. 값을 평가하기 전에 인코딩값인지 선형값인지, 빛을 모델링하려는지 예술적 효과를 원하는지 확인해야 한다.
디코딩하고 계산한 뒤 인코딩한다
실용적인 순서는 짧다. 인코딩 성분을 선형광으로 바꾸고 빛에 해당하는 연산을 한 뒤 저장·표시용으로 되돌린다. 변환을 두 번 적용하지 않도록 주의한다. 다음 단계가 숫자를 해석할 수 있게 파일과 앱에도 올바른 색 공간 정보가 필요하다.
모든 어두운 혼합이 버그라는 뜻은 아니다. 계산에는 의미가 있다는 뜻이다. 같은 양의 빛을 섞으려는 경우 인코딩값의 단순 평균은 다른 질문에 답한다. 공간을 명시하면 숨어 있던 선택을 검토할 수 있다.
더 읽어 보기
W3C CSS Color: predefined sRGB space ↗W3C CSS Color: sample conversion code ↗공식 문서와 함께 읽으면 좋은 자료입니다.
