그림자 매핑

편집 역사 토론
컴퓨터 그래픽스 게임 개발 마지막 수정: 2026-07-13 04:31:26

1. 개요[편집]

그림자가 뭐냐고? 광원이 못 본 곳이다. 그럼 광원 시점에서 한 번 찍어보면 되겠네.

그림자 매핑(Shadow mapping)은 광원의 시점에서 장면의 깊이(depth)를 미리 렌더링해 저장해 두고(그림자 맵), 실제 카메라 렌더링 때 각 픽셀을 광원 공간으로 변환해 깊이를 비교함으로써 그 점이 그림자 안에 있는지 판정하는 실시간 그림자 기법이다. 1978년 Lance Williams가 제안했고1, 광선을 일일이 쏘지 않고도 한 번의 추가 렌더 패스로 그림자를 얻을 수 있어 지난 40여 년간 실시간 렌더링의 사실상 표준 그림자 기법으로 군림해 왔다.

핵심 아이디어는 그림자의 정의를 뒤집는 것이다. **“광원에서 어떤 표면점까지 가는 길에 다른 물체가 가로막고 있으면 그림자”**인데, 이걸 광원 시점에서 보면 “광원이 볼 수 있는 가장 가까운 표면만 밝고, 그 뒤는 전부 그림자”가 된다. 그래서 광원에서 본 각 방향의 최단 깊이만 기록해 두면, 나중에 임의의 점이 그 최단 깊이보다 멀리 있는지(=가려졌는지)를 비교 한 번으로 알 수 있다.

2. 두 패스 알고리즘[편집]

그림자 매핑은 두 번의 렌더 패스로 구성된다.

1패스 — 깊이 렌더링: 카메라를 광원 위치에 놓고 장면을 렌더링하되, 색은 버리고 깊이 버퍼만 텍스처(그림자 맵)로 저장한다. 이 텍스처의 각 텍셀은 “광원에서 그 방향으로 가장 가까운 표면까지의 거리”를 담는다. 방향광은 직교 투영, 점광·스포트라이트는 원근 투영을 쓴다.

2패스 — 그림자 판정: 카메라 시점에서 정상적으로 장면을 그리면서, 각 프래그먼트의 월드 좌표 p\mathbf{p}를 광원의 뷰-투영 행렬로 변환해 그림자 맵 좌표 (u,v)(u, v)와 광원 기준 깊이 dd를 얻는다. 그리고 그 좌표의 저장된 깊이 zmapz_{\text{map}}과 비교한다.

shadow(p)={1dε>zmap(u,v)0otherwise\text{shadow}(\mathbf{p}) = \begin{cases} 1 & d - \varepsilon > z_{\text{map}}(u,v) \\ 0 & \text{otherwise} \end{cases}

dd가 저장된 깊이보다 멀면 그 사이에 뭔가 가로막고 있다는 뜻이니 그림자(1), 아니면 빛을 받는다(0). 여기서 ε\varepsilon이 바로 그 악명 높은 **깊이 편향(depth bias)**인데, 이게 없으면 지옥이 열린다.

3. 그림자 여드름과 피터 패닝[편집]

그림자 매핑을 처음 구현하면 반드시 만나는 두 가지 아티팩트가 있다. 둘 다 깊이 편향 ε\varepsilon과 얽혀 있고, 서로 반대 방향으로 당긴다.

  • 그림자 여드름(shadow acne): 편향이 부족할 때 생긴다. 그림자 맵의 텍셀은 유한한 해상도라 하나의 텍셀이 표면의 넓은 영역을 대표하는데, 표면이 광원에 비스듬할수록 같은 텍셀 안에서 실제 깊이가 들쭉날쭉해진다. 그 결과 밝아야 할 표면이 스스로를 가리며(self-shadowing) 얼룩말 무늬 줄무늬가 생긴다.2
  • 피터 패닝(peter panning): 여드름을 없애려고 편향을 너무 키우면 반대로 그림자가 물체 발밑에서 떨어져 나가, 캐릭터가 공중에 붕 뜬 것처럼 보인다. 피터팬처럼 그림자와 분리된다고 이 이름이 붙었다.

이 둘 사이의 좁은 골짜기를 찾는 게 그림자 매핑 튜닝의 절반이다. 표면 기울기에 비례해 편향을 주는 경사 스케일 편향(slope-scaled bias), 앞면 대신 뒷면을 그림자 맵에 렌더링하는 프론트페이스 컬링, 두 깊이의 중간값을 쓰는 노멀 오프셋 등이 실전 대응책이다.

4. 부드러운 그림자와 앨리어싱 대책[편집]

기본 그림자 매핑의 판정은 0 아니면 1이라, 그림자 경계가 텍셀 단위로 계단처럼 각진다. 이걸 부드럽게 만드는 게 다음 과제.

  • PCF(Percentage-Closer Filtering): 그림자 맵을 한 텍셀만 보지 말고 주변 n×nn \times n 텍셀에서 각각 깊이 비교를 한 뒤, 그림자인 비율을 평균낸다. 경계에 부드러운 반음영(penumbra)을 만든다. 가장 널리 쓰이는 국룰.
  • VSM(Variance Shadow Maps): 깊이의 평균과 분산을 저장하고 체비쇼프 부등식으로 그림자 확률을 추정. 미리 블러를 적용할 수 있어 부드럽지만, 빛 번짐(light bleeding) 아티팩트가 흠.
  • CSM(Cascaded Shadow Maps): 넓은 야외 장면에서 카메라 절두체를 거리별로 여러 구간(cascade)으로 쪼개, 가까운 곳은 고해상도 그림자 맵, 먼 곳은 저해상도를 배정한다. 방향광(태양) 그림자의 원근 앨리어싱을 잡는 사실상 표준.3

5. 레이 트레이싱 그림자와의 비교[편집]

그림자 매핑의 대안은 레이 트레이싱으로 그림자 광선(shadow ray)을 직접 쏘는 것이다. 표면점에서 광원으로 광선을 쏴 도중에 뭔가에 맞으면 그림자. 이 방식은 편향·해상도·피터패닝 같은 그림자 맵 특유의 골칫거리가 원천적으로 없고, 경계 볼륨 계층으로 가속하면 픽셀 단위로 정확한 경계를 준다.

대신 비용이 다르다. 그림자 매핑은 광원당 텍스처 한 장이면 화면 해상도와 무관하게 저렴한 반면, 레이 트레이싱 그림자는 픽셀마다(부드러운 그림자면 픽셀당 여러 광선) 트리 순회 비용을 치른다. 최근 RTX 세대 하드웨어 레이 트레이싱이 대중화되며 하이엔드에서는 레이트레이스드 그림자가 늘고 있지만4, 모바일·중급기와 대다수 게임에서는 여전히 그림자 매핑(특히 CSM+PCF)이 주력이다. 물리 기반 렌더링전역 조명 파이프라인에서도 직접광 그림자는 그림자 맵으로, 간접광은 별도 기법으로 나눠 처리하는 하이브리드가 흔하다.

6. 관련 문서[편집]

7. Footnotes[편집]

  1. Williams, L. (1978). Casting Curved Shadows on Curved Surfaces. SIGGRAPH. 반세기 가까이 된 아이디어가 아직도 게임 그래픽 옵션 메뉴에 “그림자 품질”로 살아 있다. 잘 만든 알고리즘은 늙지 않는다.

  2. 여드름(acne)이라는 작명은 정확히 그 얼룩덜룩한 표면 무늬 때문이다. 사춘기 피부와 3D 렌더링이 같은 단어를 공유하는 흔치 않은 순간.

  3. 태양광 그림자를 화면 전체에 균일한 해상도로 깔면, 발밑 그림자는 뭉개지고 지평선 그림자는 낭비된다. 카메라와 가까운 곳에 텍셀 예산을 몰아주는 CSM이 이 불균형을 해결한다. 사실상 그림자판 LOD(Level of Detail).

  4. 하드웨어 레이 트레이싱은 경계 볼륨 계층 순회를 전용 코어로 가속한다. 그림자 광선은 “맞았냐 안 맞았냐”만 필요해 가장 싼 종류의 광선이라, 실시간 레이 트레이싱이 가장 먼저 실용화된 용도가 바로 그림자였다.