Quick Flow
1. 빛의 view-projection으로 occluder depth를 shadow map에 기록
2. 카메라 pass에서 world position을 같은 light space로 변환
3. current light depth와 stored depth를 같은 규약으로 비교
4. shadow factor를 direct lighting에만 적용| 설정 | 무엇을 바꾸는가 | 너무 작거나 크면 |
|---|---|---|
| Shadow map resolution | 한 texel이 덮는 light-space 면적 | 작으면 계단과 aliasing, 크면 memory와 shadow pass 시간 증가 |
| Light projection bounds | depth precision과 texel 분포 | 넓으면 가까운 그림자가 흐림, 좁으면 caster/receiver가 잘림 |
| Depth bias | self-shadowing 보정 | 작으면 acne, 크면 peter panning |
| Normal bias | 표면 normal 방향으로의 보정 | 크면 접촉부가 분리되고 thin geometry가 흔들림 |
| Filter / PCF kernel | 여러 comparison 결과 평균 | 작으면 거친 경계, 크면 비용과 light leaking 증가 |
| Cascade split / blend | directional light의 거리별 map 배분 | split이 거칠면 경계선과 품질 급변 |
depth 비교 계약
그림자 매핑은 “빛이 볼 수 있는 표면만 밝다”는 관점으로 동작합니다. 먼저 빛의 시점에서 장면을 렌더링해 각 위치에서 가장 가까운 깊이를 저장합니다. 이후 카메라 렌더링에서 현재 fragment를 빛의 좌표로 변환하고, shadow map의 깊이보다 뒤에 있으면 빛을 받지 못한다고 판단합니다.
currentLightDepth > shadowMapDepth + bias
-> in shadowshadow map의 좌표 해석은 두 번의 변환을 거칩니다. world position을 light view-projection으로 보내고, 그 결과를 shadow texture의 UV와 depth 범위로 바꿔 비교합니다. 이 매핑이 흔들리면 그림자가 수영하듯 떨릴 수 있습니다. 밖으로 투영된 UV, light frustum 앞/뒤, normal/reversed depth, depth texture compare sampler의 규칙도 명확히 정해야 합니다.
Bias
shadow acne은 표면 자신이 자기 그림자를 만드는 현상입니다. depth precision과 rasterization 차이 때문에 현재 깊이가 shadow map 깊이보다 조금 뒤로 계산될 수 있습니다. bias는 이 차이를 보정하지만, 너무 크면 그림자가 물체에서 떨어져 보이는 peter panning이 생깁니다.
PCF는 shadow map을 한 번만 읽지 않고 주변 여러 texel을 읽어 평균을 냅니다. 경계는 부드러워지지만 샘플 수가 늘수록 texture fetch 비용도 늘어납니다. PCF는 penumbra 크기를 물리적으로 계산하는 soft shadow가 아니라 filtering이므로, 넓은 light의 거리별 penumbra까지 맞추려면 다른 기법이나 별도 근사가 필요합니다.
directional light의 넓은 그림자는 한 장의 shadow map으로 품질을 유지하기 어렵습니다. cascade shadow map은 카메라 가까운 영역과 먼 영역을 나누어, 가까운 곳에 더 높은 해상도를 배정하는 방식입니다. Cascaded shadows and filtering 카드에서 split과 stable projection을 이어서 확인할 수 있습니다.
caster와 receiver 설정
| 대상 | shadow pass에서 맞출 것 | 놓치기 쉬운 점 |
|---|---|---|
| Alpha cutout foliage | 같은 alpha texture, cutoff, mip 선택 | main pass와 silhouette가 다르면 그림자 경계가 어긋남 |
| Vertex displacement | 같은 displacement 또는 보수적인 bounds | 화면 mesh와 shadow mesh 위치가 다름 |
| Skinned mesh | 최신 bone transform과 bounds | update 순서가 늦으면 한 frame 그림자가 밀림 |
| Transparent glass | shadow를 cast할지와 transmittance 정책 | 일반 depth map은 반투명 색을 자동으로 보존하지 않음 |
| Point light | 6방향 또는 cubemap projection | face 경계와 far plane precision |
shadow pass는 단순히 모든 object를 depth-only로 다시 그리는 작업이 아닙니다. 어떤 object가 cast하고 receive하는지, alpha/displacement가 main material과 동일한지, shadow map의 near/far와 projection bounds가 light 종류에 맞는지를 정해야 합니다.
품질 기준
| 증상 | 의심할 원인 |
|---|---|
| 그림자 표면에 줄무늬 | bias 부족, depth precision |
| 그림자가 떠 보임 | bias 과도 |
| 그림자가 계단짐 | shadow map 해상도 부족 |
| 멀리서 품질 저하 | cascade 필요 |
| 가장자리가 딱딱함 | PCF, filtering |
| 움직일 때 떨림 | texel snapping, 안정화 필요 |
shadow map은 결국 texture입니다. 해상도, projection 범위, filtering, depth precision이 품질을 결정합니다. 해상도만 올리기 전에 light projection을 caster와 receiver 주변으로 타이트하게 잡고, frame capture에서 map에 실제로 어떤 object와 depth가 기록됐는지 확인하는 편이 우선입니다.
실패 신호
light direction 또는 camera가 아주 조금 움직일 때 그림자 edge가 흔들리면 texel snapping과 cascade stabilization을 먼저 봅니다. bias를 한 값으로 모든 material에 적용하면 slope가 큰 면, thin mesh, normal map이 강한 면에서 서로 다른 오류가 남습니다. depth bias와 normal bias는 scene scale, map resolution, light angle을 보며 조정하십시오.
참고 링크
1 sources