컴퓨터 그래픽
사진 한 장, 글자 하나, 게임 화면 한 프레임이 숫자에서 픽셀이 되기까지의 과정을 정리한다.
목차 (8)
디지털 이미지는 숫자 표다
이미지는 픽셀의 격자이고, 픽셀마다 색을 나타내는 숫자가 있다. 보통 빨강·초록·파랑 세 채널에 각각 0~255(8비트) 값을 두고, 투명도를 나타내는 알파 채널을 더하기도 한다. 1920×1080 이미지는 약 200만 픽셀이라, 압축하지 않으면 픽셀당 4바이트로 약 8MB다. 그래서 파일로 저장할 때는 PNG·JPEG·WebP 같은 압축을 쓴다(데이터 탭 참고).
채널 하나가 몇 비트인지가 비트 깊이다. 8비트는 2⁸ = 256단계, 10비트는 1,024단계다. 픽셀마다 색을 가장 가까운 단계로 반올림하므로, 하늘처럼 천천히 변하는 그러데이션에서는 단계 경계가 줄무늬로 보인다. 이것이 밴딩(banding)이다. 단계를 늘리거나, 반올림 오차를 작은 무늬로 흩뿌리는 디더링(dithering)으로 경계를 눈에 덜 띄게 한다. 모니터 쪽 비트 깊이는 모니터 노트에 있다.
색 모델과 색 공간
- 색 모델은 색을 숫자로 적는 방법이다. RGB는 빛의 세 성분, HSL·HSV는 색상·채도·밝기로 적는다. 같은 색을 다른 방법으로 적은 것뿐이다.
- 색 공간은 그 숫자가 실제로 어떤 색인지 정한 약속이다. 같은
rgb(255, 0, 0)도 sRGB에서와 Display P3에서의 빨강은 다르다. P3의 빨강이 더 진하다. 색 공간이 담을 수 있는 색의 범위를 색 영역(gamut)이라 한다. - 감마: 사람 눈은 어두운 쪽의 차이에 더 민감하다. 그래서 숫자를 밝기에 곧바로 비례시키지 않고 어두운 쪽에 단계를 더 배분해 저장한다. 색을 섞거나 흐릴 때 이 곡선을 무시하면 경계가 탁하게 어두워진다.
같은 색을 HEX·RGB·HSL로 바꿔 보려면 색상 변환 도구를 쓴다.
혼합 모드는 픽셀끼리의 계산이다
레이어를 겹칠 때 위 색(A)과 아래 색(B)을 0~1로 놓고 채널마다 계산한다.
| 모드 | 계산 | 결과 |
|---|---|---|
| 보통 | A | 위 색이 덮는다 |
| 곱하기 | A × B | 항상 어두워진다. 흰색은 변화 없음 → 그림자·선화 |
| 스크린 | 1 − (1 − A)(1 − B) | 항상 밝아진다. 검정은 변화 없음 → 빛·불꽃 |
| 오버레이 | B가 어두우면 곱하기, 밝으면 스크린 | 대비가 세진다 |
이 사이트의 이미지 편집에서 레이어 혼합 모드를 직접 바꿔 볼 수 있다.
벡터와 래스터
- 래스터는 픽셀로 저장한다(사진). 확대하면 계단이 보인다. 벡터는 도형을 수식으로 저장한다(SVG·폰트). 아무리 키워도 매끄럽다.
- 곡선은 대부분 베지어 곡선이다. 시작점·끝점과 그 사이를 끌어당기는 조절점(핸들)으로 정의한다. 디자인 툴의 펜 도구 핸들이 바로 이 조절점이다.
- 화면은 결국 픽셀이므로, 벡터 도형도 어느 픽셀을 칠할지 계산해야 한다. 이것이 래스터화다. 경계에 걸친 픽셀을 덮인 비율만큼 반투명하게 칠하면 계단이 덜 보인다. 이것이 안티에일리어싱이다.
펜 도구로 베지어 곡선을 직접 그려 보려면 펜툴 연습에서 목표 모양을 따라 그리며 핸들 다루는 법을 익힐 수 있다.
이 사이트의 폰트 만들기는 그린 글자를 이런 곡선 윤곽으로 바꿔 TTF에 담는다.
GPU가 한 프레임을 그리는 순서
- 정점 처리 — 3D 모델은 삼각형 묶음이다. 꼭짓점마다 카메라 기준 화면 위치를 계산한다(정점 셰이더).
- 래스터화 — 화면에 놓인 삼각형이 덮는 픽셀을 찾는다.
- 픽셀 처리 — 덮인 픽셀마다 빛·질감·그림자를 계산해 색을 정한다(프래그먼트·픽셀 셰이더). 가장 앞에 있는 것만 남기려고 깊이(depth)를 비교한다.
- 후처리 — 블룸·블러·색 보정 같은 효과를 화면 전체에 건다.
이것은 GPU가 그리기 작업을 처리하는 큰 흐름이다. 브라우저의 레이아웃·페인트, 게임의 여러 렌더 패스, 그래픽 툴의 레이어·노드 합성까지 포함한 비교는 컴퓨터 그래픽스 노트의 렌더링 파이프라인에 있다.
셰이더는 이 단계에서 GPU가 정점이나 픽셀마다 실행하는 작은 프로그램이다. 픽셀 수백만 개에 같은 프로그램을 동시에 돌리기 때문에, 코어가 적고 강한 CPU보다 단순한 코어 수천 개를 가진 GPU가 잘한다.
삼각형 대신 SDF(점에서 도형 표면까지의 거리를 돌려주는 함수)로 장면을 정의하는 방법도 있다. 픽셀마다 광선을 쏘고, 거리만큼씩 전진하며 표면을 찾는다(레이 마칭). 부드럽게 녹아 붙는 도형을 수식 몇 줄로 만들 수 있다.
이 사이트의 3D 뷰어가 이 과정을 브라우저의 WebGL로 실행한다.
블러는 이웃 픽셀의 가중 평균이다
블러는 각 픽셀을 주변 픽셀과 섞어 새 값을 만든다. 이웃마다 얼마나 섞을지 적은 작은 표를 커널이라 한다. 모두 같은 비율이면 박스 블러, 가운데가 크고 가장자리로 갈수록 작아지는 종 모양(정규 분포)이면 가우시안 블러다. 가우시안이 더 자연스럽게 보인다. 박스 블러를 여러 번 겹치면 가우시안에 가까워지므로, 빠르게 계산할 때 이 방법을 쓰기도 한다. 이 사이트의 이미지 편집 블러도 이 방식이다.
크기 바꾸기도 이웃 픽셀의 가중 평균이다
이미지를 키우거나 줄이면 새 격자의 픽셀이 원래 픽셀 사이에 떨어진다. 그 자리의 색을 어떻게 정하느냐가 리샘플링(보간) 방식이다.
| 방식 | 계산 | 결과 |
|---|---|---|
| 최근접(nearest) | 가장 가까운 픽셀 하나를 그대로 쓴다 | 가장 빠르고 경계가 날카롭다. 매끄러운 사진은 계단이 진다 → 픽셀 아트 확대 |
| 쌍선형(bilinear) | 둘레 4개를 거리 비율로 섞는다 | 부드럽지만 날카로운 선이 흐려진다 |
| 쌍삼차(bicubic) | 둘레 16개를 곡선으로 섞는다 | 쌍선형보다 선명하고 계산이 더 든다 |
| Lanczos | 더 넓은 이웃을 sinc 함수에 가까운 가중치로 섞는다 | 쌍삼차보다 결과가 좋은 편이고 계산이 가장 많다 |
줄일 때가 더 까다롭다. 반 넘게 줄이면 쌍선형·쌍삼차는 이웃하지 않은 픽셀만 띄엄띄엄 읽어 정보를 버리고 지글거리는 무늬(에일리어싱)가 생긴다. 먼저 흐려서 고운 무늬를 지운 뒤 줄이거나, 새 픽셀 하나가 덮는 원래 픽셀을 모두 평균해야 한다. 게임은 미리 반씩 줄여 둔 사본(밉맵)으로 이 문제를 푼다(컴퓨터 그래픽스 노트).
흔한 오해
- “같은 RGB 값이면 어디서나 같은 색” — 색 공간과 모니터가 다르면 다르게 보인다.
- “벡터는 무조건 래스터보다 낫다” — 사진처럼 복잡한 색은 벡터로 담기 어렵다. 용도가 다르다.
- “DPI를 300으로 바꾸면 화질이 좋아진다” — 파일의 DPI(정확히는 PPI) 값은 인쇄할 때의 크기만 정한다. 1000×1000 픽셀은 값을 바꿔도 1000×1000 픽셀이고, 픽셀 수는 리샘플링해야만 바뀐다.
- “게임 그래픽은 전부 레이 트레이싱이다” — 대부분은 여전히 래스터화가 기본이고, 반사·그림자 일부에만 광선 추적을 섞는다.
- The Book of Shaders — 프래그먼트 셰이더를 처음부터 따라 배우는 무료 책
- LearnOpenGL — GPU 렌더링 파이프라인을 코드로 익히는 입문서
- Scratchapixel — 레이 트레이싱·래스터화를 원리부터 설명
- Inigo Quilez 글 모음 — SDF와 레이 마칭의 바이블
- Physically Based Rendering — 사실적 렌더링 이론서, 온라인 무료
- Bartosz Ciechanowski — 직접 만져 보는 대화형 원리 설명
- Making Software: Digital images — Dan Hollick, 유료 전자책
- Making Software: Blending modes — Dan Hollick, 유료 전자책
- Making Software: Rasterisation and anti-aliasing — Dan Hollick, 유료 전자책
- Making Software: Shaders — Dan Hollick, 유료 전자책
- Making Software: Rays and SDFs — Dan Hollick, 유료 전자책
- Making Software: Blurs, noise and other effects — Dan Hollick, 유료 전자책
- Image scaling — Wikipedia — 최근접·쌍선형·쌍삼차·Lanczos 보간과 축소할 때의 에일리어싱
- Colour banding — Wikipedia — 비트 깊이가 모자랄 때 그러데이션에 생기는 줄무늬
- Dots per inch — Wikipedia — 파일의 PPI 값은 인쇄 크기만 정하고 픽셀 수를 바꾸지 않는다
- Dan Hollick (X) — Making Software 저자