Quick Flow
sRGB 색 이미지 → sRGB internal format에서 샘플링 시 선형화
→ 선형 공간의 조명·혼합 → 필요하면 부동소수 HDR 첨부
→ tone mapping → sRGB 출력 변환을 한 번 적용 → 표시일반 색 이미지와 법선·거칠기 같은 데이터 이미지를 구분합니다. sRGB 텍스처 읽기 변환과 FRAMEBUFFER_SRGB 쓰기 변환은 다른 단계입니다.
형식과 상태
| 선택 | 동작 | 사용·실패 조건 |
|---|---|---|
| SRGB8/SRGB8_ALPHA8 | 샘플링 RGB를 선형으로 해석 | 색 자료에 사용, 알파는 sRGB 감마 성분이 아님 |
| RGB8/RGBA8 | 정규화된 저장, 자동 sRGB 해석 없음 | 법선·마스크 등 데이터에 적절한지 판단 |
| RGBA16F 등 | 1보다 큰 값 등의 HDR 저장 | 메모리·대역폭·렌더 가능 형식 확인 |
| FRAMEBUFFER_SRGB | 초기 비활성 | sRGB 대상에 쓸 때 선형→sRGB 변환 |
| 기본 창 framebuffer | 창 시스템이 결정 | sRGB 요청과 실제 encoding 확인 |
sRGB 상태를 켰다고 선형 형식의 모든 출력 대상이 sRGB로 바뀌지는 않습니다. 대상 첨부의 색 인코딩을 확인합니다. 여러 색 첨부가 서로 다른 형식이면 각각의 조건이 적용됩니다.
대표 출력 구간
// GL 3.3 Core: 실제 sRGB 색 첨부를 가진 framebuffer를 선택했습니다.
glEnable(GL_FRAMEBUFFER_SRGB);
// 프래그먼트 셰이더는 여기서 선형 RGB를 출력합니다.
// 수동 gamma 보정은 동시에 하지 않습니다.색 텍스처가 이미 샘플링 과정에서 선형화되었는데 셰이더에서 다시 pow를 적용하면 이중 변환입니다. 반대로 일반 RGBA8로 올린 sRGB 파일을 아무 변환 없이 조명식에 넣으면 밝기·혼합 결과가 틀어질 수 있습니다. 정상처럼 보이는 한 장면의 노출값 조정으로 전체 규약 오류를 숨기지 않습니다.
출력 인코딩 조회
사용자 FBO의 COLOR_ATTACHMENT0에 실제 이미지가 연결된 GL 3.3 예입니다. 색 인코딩이 sRGB일 때만 자동 쓰기 변환을 선택합니다.
GLint encoding = GL_LINEAR;
glGetFramebufferAttachmentParameteriv(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING, &encoding);
if (encoding == GL_SRGB) glEnable(GL_FRAMEBUFFER_SRGB);
else glDisable(GL_FRAMEBUFFER_SRGB);기본 창 framebuffer에서는 attachment를 GL_BACK_LEFT(이중 버퍼) 또는 GL_FRONT_LEFT(단일 버퍼)처럼 실제 창 버퍼로 조회해야 합니다. COLOR_ATTACHMENT0을 기본 창에 그대로 쓰지 않습니다. 선형 출력 대상을 최종 sRGB 표시로 보낼 때는 마지막 출력 단계에서 필요한 변환을 정하며, 위의 else가 모든 표시 환경에서 감마 처리가 필요 없다는 뜻은 아닙니다.
HDR과 표시
HDR 저장소를 쓴다고 최종 모니터 출력까지 HDR 형식이 되는 것은 아닙니다. 화면에 표시할 범위로 tone mapping하고 출력 인코딩을 맞춥니다. 단순 clamp는 밝은 영역의 차이를 잃을 수 있습니다. tone mapping·노출 알고리즘은 Graphics HDR에 있습니다.
프레임버퍼 혼합도 선형 공간에서 수행하도록 형식·상태를 맞춥니다. 텍스처에 들어 있는 색·버텍스 색·상수 재질색이 어떤 공간인지 함께 정하고, 알파를 RGB 감마 변환과 묶어 바꾸지 않습니다.
버전 경계
sRGB 텍스처 형식은 2.1, framebuffer sRGB 경로는 3.0 코어 조건을 확인합니다. 1.x 자료의 단순 색 연산과 현대 선형 조명 예제를 비교할 때 데이터 인코딩도 달라질 수 있습니다. 창 라이브러리의 sRGB-capable 요청은 실제 버퍼 확인을 대신하지 않습니다.
참고 링크
3 sources