현대 비디오 게임을 플레이할 때 가장 흔하게 볼 수 있는 그래픽 아티팩트 중 하나는, 반투명한 유리나 파티클 이펙트, 잔디 등이 카메라 초점 안에 있음에도 불구하고 마치 초점 밖에 있는 것처럼 부자연스럽게 흐려지는 현상이다.


이 현상이 발생하는 이유는 Depth of Field(DOF) 효과가 깊이 버퍼(Depth Buffer)에 기록된 단일 값을 기반으로 블러 반경(Circle of Confusion)을 계산하기 때문이다.
그러나 반투명 오브젝트는 구조적으로 픽셀마다 여러 단계의 깊이를 동시에 지닌다.
예를 들어, 반투명 유리 뒤에 또 다른 유리들이 나열된 경우를 생각해보자.

카메라는 반투명한 물체 뒤의 물체까지 모두 비쳐 보게 된다. 즉, 최종 이미지에는 여러 오브젝트가 겹쳐 있지만, 깊이 버퍼에는 오직 하나의 깊이 값만 기록된다.
하지만 깊이 버퍼는 각 픽셀에 대해 오직 하나의 깊이 값만 기록할 수 있다.
결국 여러 깊이 중 하나만 선택해야 하는 상황이 생긴다.
불투명 오브젝트만 있었다면 문제가 되지 않는다. 가장 앞에 있는 표면이 뒤를 완전히 가리기 때문에, 하나의 픽셀에 여러 사물이 그려지지 않는다.
따라서 깊이 버퍼는 항상 올바른 “가장 가까운 깊이” 하나만 담고 있고, DOF는 그 값을 참조해도 문제가 없다.
하지만 전면에 반투명 오브젝트가 위치하면 이야기가 달라진다. 하나의 픽셀에는 여러 오브젝트가 동시에 존재하지만 깊이 버퍼는 오직 하나만 기록할 수 있다. 일반적으로는 가장 가까운 불투명 오브젝트의 깊이를 남기도록 렌더링 파이프라인을 구현하기 때문에, 실제로 더 앞에 있는 반투명 오브젝트가 무시된다.
이 문제를 반투명 오브젝트 기준으로 바꿔도 완전히 해결되지는 않는다. 전경 반투명의 깊이를 사용하면 DOF는 전경을 올바르게 처리하지만, 그 뒤의 불투명 오브젝트가 함께 그려질 때는 여전히 깊이가 맞지 않아 시각적 모순이 발생한다.
결국 DOF는 전경과 후경 중 하나만 선택할 수밖에 없으며, 이로 인해 경계 번짐(Halo)이나 경계 줄무늬(Edge Fringe) 같은 아티팩트가 발생한다.
단순화된 사례: 전경과 후경
다음과 같은 예시를 생각해보자.
• 전경(Foreground): 반투명한 유리
• 후경(Background): 불투명한 큐브
케이스 1 – 깊이 버퍼를 전경 기준으로 기록
• 깊이 버퍼에는 유리의 앞면 깊이만 기록된다.
• DOF는 이 깊이를 참조해 블러 반경을 계산한다.
• 결과적으로 큐브는 실제보다 덜 흐려지고, 유리는 배경 DOF와 섞이며 어색하게 표현된다.
케이스 2 – 깊이 버퍼를 후경 기준으로 기록
• 깊이 버퍼에는 불투명 오브젝트인 큐브의 깊이가 기록된다.
• DOF는 이 깊이를 참조해 블러 반경을 계산한다.
• 결과적으로 유리는 실제보다 과하게 흐려진다.
즉, 어떤 기준을 선택하든 시각적인 어색함은 피할 수 없다.
해결법?
이 문제의 현실적인 근본적 해결책은 없다.
- DOF는 효과 계산 시점에 단 하나의 깊이를 선택해야 한다.
- 픽셀 단위로 여러 깊이를 동시에 고려하는 다층 DOF(Multi-layer DOF)는 학술적으로는 제안된 바 있으나, 실시간 렌더링에서는 지나치게 비싸다.
따라서 현재 상용 게임 엔진들이 제공하는 DOF는 모두 이 제약을 안고 있다.
대응 방법들
완벽하지는 않지만, 시각적으로 덜 어색하게 만들기 위한 차선책들이 존재한다.
Depth 버퍼를 Transparent 패스 이후에 캡쳐
렌더링 순서를
- 오파크 패스 → Depth 카피 → Transparent 패스 → 후처리
에서 - 오파크 패스 → Transparent 패스 → Depth 카피 → 후처리
로 바꾸는 방식이다.
이 경우 전경 반투명 오브젝트의 깊이가 DOF에 반영된다.
조건
- 대부분의 Transparent 셰이더는 ZWrite Off 상태라 그대로는 깊이에 기록되지 않는다.
- 따라서 Depth Prepass나 DepthOnly Pass를 셰이더에 추가해 반투명 실루엣을 깊이에 남겨야 한다.
단점
- 반투명이 깊이를 덮어쓰면 후처리 이펙트들이 꼬인다.
- 소프트 파티클은 자기 깊이에 막혀 스스로 깎여 나가는 현상이 발생한다.
- 포그는 실제보다 가까운 깊이를 참조해 과소 적용된다.
- SSR(Screen Space Reflection)은 반사가 조기 종료되어 끊겨 보인다.
- Depth Copy를 두 번 수행해야 하므로 GPU 대역폭과 메모리 비용이 증가한다.
Depth Prepass
- 반투명 오브젝트의 실루엣만 깊이에 기록한다.
- 전경 가장자리에 배경 DOF가 새어 들어오는 문제를 막을 수 있다.
- 단점: 알파 클리핑 기반이라 투명도 그라데이션은 표현할 수 없고, 경계가 딱딱해지거나 디더링 노이즈가 발생한다.
카메라 스태킹 / Separate Translucency
- Base 카메라: 불투명 전용 → DOF 포함 후처리 완료.
- Overlay 카메라: 투명 전용 → 별도로 DOF 적용 후 Base와 합성.
이 방식은 언리얼 엔진의 Separate Translucency와 같은 아이디어다. 투명한 파티클이나 유리 오브젝트에 별도의 DOF를 적용해, 배경과 독립적으로 흐려지도록 할 수 있다.
단점
- DOF와 후처리를 두 번 실행하기 때문에 GPU 비용이 크게 늘어난다.
- 두 카메라 결과를 합성할 때 경계에서 어색한 겹침이 생겨 보정 작업이 필요하다.
- 특히 Bloom, 색 보정(Color Grading) 같은 후처리를 어디에서 적용할지도 세밀하게 조율해야 한다.
+ 마스크 기반 보정하기
DOF를 두 번 적용하는 경우, 단순히 합성하면 경계가 번지거나 잘못 겹치는 문제가 생긴다. 이를 줄이기 위해 전경 마스크를 추가적으로 가공한다.
- 팽창(Dilate) 대응하기: 마스크를 바깥으로 조금 넓혀서 배경 블러가 전경 내부로 새는 문제를 막는다.
- 침식(Erode) 대응하기 : 마스크를 안쪽으로 줄여서 전경 블러가 외곽으로 번져 나가는 문제를 줄인다.
- 스텐실 컷(Stencil Cut): 스텐실 버퍼를 활용해 특정 영역은 배경 DOF만, 다른 영역은 전경 DOF만 출력되도록 강제한다.
이런 보정 단계를 추가하면 경계선에서의 Halo/Fringe 문제를 크게 완화할 수 있다.