커스텀 DOF, 유니티 내장 DOF의 단점을 고쳐보자
2026년 10월 2일20#unity #urp #dof +3

유니티 내장 DOF가 마음에 안 들었다. Bokeh 모드여도 흐려지는 질감이 밋밋했고, 알파가 들어간 물체에서 특히 약했다.
같은 프레임. 위부터 DOF 끔, URP 내장 Bokeh, 커스텀 Bokeh. 뒤 배경이 번지는 질감을 비교한 컷
내장 DOF는 ZWrite를 끈 반투명 물체는 깊이 텍스처에 안 남아서 픽셀마다 블러 반경을 정하는 CoC가 그 물체 거리가 아니라 뒤에 있는 배경 거리로 계산된다. URP에서 알려진 한계다. 툰셰이더 캐릭터는 파츠에 따라 알파로 그려지는 게 많은데, NiloToon은 기본 아웃라인이 깊이를 쓰는 불투명 압출 방식이고 두꺼운 아웃라인 옵션이나 반투명 프리셋 쪽이 여기에 걸린다.
샘플 씬에 아웃라인 대신 반투명 링을 하나 띄워서 원리만 재현해 봤다.
초점 거리에 놓은 반투명 링. 내장은 링이 뒤 배경의 초점을 받아 흐려지고, 커스텀은 투명 깊이 반영을 켜면 링이 제 거리로 선명해진다
같은 프레임. 밤 컷에서 머리카락 윤곽 주변과 뒤 배경이 번지는 모습
유나이트 서울 2026에서 컴투스 TA 세션이 URP 패키지를 건드리지 않고 Tonemapping, Bloom, DoF를 RenderGraph 기반 커스텀 패스로 갈아끼운 사례를 발표했다. 나도 한 프로젝트에서만 쓸 게 아니라 여러 프로젝트에서 범용으로 써야 했고, 패키지를 포크하면 프로젝트마다 그걸 들고 다녀야 하는 게 제일 싫었다. 환경이 거의 같아서 같은 방향으로 갔다.
패키지 매니저로 설치하고 Setup 메뉴를 한 번 돌리면 렌더러에 피처가 하나 붙는다. DOF는 자체 패스 체인이라 URP 원본에 손댈 게 없고, 톤매퍼와 블룸은 설치된 URP의 LutBuilderHdr와 UberPost 셰이더를 복사해서 패치본을 프로젝트 안에 만든다. DOF는 BeforeRenderingPostProcessing 직전에 돌아서 블룸과 톤매핑보다 앞이다. 렌즈 효과 다음에 센서와 화면 효과 순서를 그대로 따른다.
렌더러 인스펙터. 렌더 피처 목록에 Custom Post Process Feature가 하나 붙어 있다
예전에 사진 찍는 취미가 있었다. 조리개, 셔터스피드, ISO가 맞물려서 사진이 나오는 원리를 알고 있었던 게 구현을 빠르게 만들었다. CoC를 거리 램프로 대충 짜는 대신 렌즈 식으로 가면 된다는 걸 처음부터 알았기 때문이다.
최우선 목표는 초점거리랑 조리개 값을 넣으면 현실 카메라처럼 보케가 나오는 Physical 모드였다. 연출용으로 거리 램프를 직접 잡는 Artistic 모드도 따로 둔다.
같은 씬, 초점 6m, 85mm 고정. 조리개만 f/1.4, f/2.8, f/5.6, f/11
같은 씬, 초점 6m, f/2.8 고정. 초점거리만 24mm, 50mm, 85mm, 135mm
같은 프레임. 얼굴 클로즈업, 얕은 심도에서 뒤 배경이 번지는 모습
품질 모드는 둘이다. Cinematic은 gather 탭을 42, 105, 196개 중에 고르고, Normal은 필터와 블러 단계를 덜어낸 성능 모드다. 발표에서도 품질과 성능 모드를 나눴길래 같은 구성으로 갔다. 기존 프로젝트를 옮길 때를 위해 내장 DepthOfField 값을 그대로 읽어서 Normal로 그려주는 호환 옵션도 넣었다.
시네머신과 같이 쓰는 경우가 많아서 Cinemachine Volume Settings의 Focus Tracking에 타겟을 걸면 포커스를 따라가는 기능이 있는데 기능을 그대로 사용할 수 있도록 조치했다. 프로파일에 내장 DoF 오버라이드를 넣을 필요는 없고, 시네머신이 내장 focusDistance에 쓰는 식, 그러니까 타겟까지 거리에 Focus Offset을 더한 값을 활성 vcam에서 직접 읽는다. 스크립트로 초점을 움직일 땐 VolumeManager.stack에 직접 쓰면 되는 간단한 구현이다.
같은 프레임. 서로 다른 거리에 선 여러 캐릭터
같은 프레임. 네 명이 같이 잡힌 컷
유나이트 서울 세션에서 제일 탐났던 건 디버그 표시였다. 검정이 선명한 곳이고 밝을수록 블러 반경이 큰 곳이다. 눈으로는 어디까지가 초점 안인지 애매할 때가 많은데 이걸 켜면 바로 보인다. 초점을 6m에서 14m로 옮기면 어두운 구간이 같이 뒤로 밀려난다. 작업 용이성 면에서 굉장히 편리함을 느꼈다.
디버그 표시. DOF 끔, 초점 6m 디버그, 초점 14m 디버그, 초점 14m 결과 화면
깨알 같은 재미로 보케 모양도 넣었다. 현실에도 렌즈 앞에 모양 구멍을 끼워서 보케를 하트나 별로 만드는 키트가 있다. 그걸 레퍼런스로 표준 원형, 오각, 하트, 별, 마름모, 도넛, 비눗방울, 크리미, 아나모픽 아홉 가지 프리셋을 만들었다.

같은 씬, 하이라이트 스캐터를 켠 상태에서 보케 모양만 바꾼 컷. 원형, 하트, 마름모, 도넛, 별, 그리고 초점 3m의 하트
실제 프로젝트에서 쓴 화면이 이쪽이다. 불꽃놀이가 하트로 번진다.
같은 프레임, DOF 끔 / URP 내장 / 커스텀. 불꽃놀이의 보케가 하트로 번진다
같은 프레임. 배경 조명 줄의 번짐 비교
같은 프레임. 벽돌 배경 앞 캐릭터 클로즈업
같은 프레임. 멀리 터지는 불꽃놀이와 인물
같은 프레임. 뒷모습 컷에서 전경과 배경이 갈리는 모습
실제 컷. 불꽃놀이가 하트로 번진다
실제 컷. 윙크하는 캐릭터 뒤로 하트 보케
실제 컷. 팔을 든 캐릭터 뒤의 불꽃놀이 보케
URP 패키지를 수정하는 대신 렌더 피처와 커스텀 Uber 포스트로 붙이니까 다른 프로젝트에 가져가기가 쉽다. 대신 URP와 셰이더에 기대는 구조라서 버전이 바뀔 때 호환을 보장할 수 없다는 점이다. 지금은 유니티 6000.3, URP 17.3 기준으로 돌아간다. 패치본을 다시 만들어 주긴 하는데 새 URP에서 패치가 맞을지는 올려 봐야 안다.
아쉬운 점도 있다. 투명 레이어 분리 같은 고품질 옵션은 DOF를 두 번 도는 셈이라 GPU 코스트가 더 든다. 뭐 알파쪽 건드리면 렌더 여러번 하는 게 무식하지만 확실하니까 대충 그렇게 구현을 해뒀다.
사용 사례는 아래 링크에서 확인
https://molayo1419.me/portfolio/ioi-suddenly-cover
태그
#unity#urp#dof#bokeh#cinemachine#toon-shader
관련 포스트
Unity 카테고리의 다른 글

DMX 개발기 - 볼류메트릭, 공간감을 찾아서
DMX 개발기 2: 현실감 넘치는 공간감 구현 비결 공개! 전역 구름 요소로 생동감 UP. 리얼리스틱한 DMX 개발 과정과 팁을 만나보세요. 지금 바로 확인하세요!
2026년 9월 19일#Unity

Unity MCP 개발기
MCP 도구를 새로 만들 때마다 에디터에 불꽃 파티클을 띄워 눈으로 확인했다. 안 보이는 파티클, 블룸에 날아간 형체를 거쳐 궤적이 살아나기까지의 기록.
2026년 8월 12일#Unity

DMX 개발기 - 볼류메트릭
다시 좀 만져보고 있다. 최근에 큰 인사이트를 얻은 뒤로 개선이 많이 된 듯 하다
2026년 7월 20일#Unity

Patch 시스템 개발
유니티 런처를 제작하여 커밋부터 배포까지 자동화된 파이프라인을 구축했다. Git 푸시/태그를 시작으로 빌드, 패치 생성, 배포를 자동화했으며, Git 커밋 메시지를 기반으로 패치노트 자동 생성 기능을 구현했다.
2026년 1월 25일#Unity