11. Renderer Feature/Pass 실전 패턴 모음(URP)
이 챕터는 “Render Feature로 구현할 수 있는 전형적 기능”들을 패턴으로 정리합니다.
11.1 패턴 1: 카메라 컬러 복사(Copy Color)
목표:
- Opaque 렌더 이후의 컬러 버퍼를 따로 저장
- 이후 패스(포스트/투명 등)에서 참조
핵심:
- RenderGraph:
CreateTexture+Blit패스 - 레거시:
_CameraColorTexture비슷한 슬롯/RTHandle 활용
RenderGraph 구현 체크리스트
- 어떤 타이밍의 컬러가 필요한가? (Opaque 이후? Transparent 이후?)
- 출력 텍스처의 포맷/해상도/스케일이 카메라 컬러와 같은가?
- 결과를 후속 패스가 접근할 수 있도록 어디에 “노출”할 것인가?
- (A)
UniversalResourceData의 activeColor 교체 - (B) 전역 슬롯(
SetGlobalTexture)에 바인딩(필요 시)
- (A)
11.2 패턴 2: Depth/Normals 기반 이펙트
목표:
- 윤곽선, SSAO, 스크린 스페이스 효과
핵심:
- URP가 Depth/Normal 텍스처를 생성하도록 설정
- 셰이더에서 해당 텍스처를 올바르게 샘플링
실전 체크리스트
- Requirements(Depth/Normal)가 충족되도록 설정했는가?
- Full Screen Pass Renderer Feature를 쓴다면 Requirements에서 체크
- 커스텀 패스라면 URP 문서/소스에 따라 입력 요구를 선언
- Raw depth를 선형화했는가? (
_ZBufferParams기반) - 노말 텍스처가 월드 노말인지 뷰 노말인지 확인했는가? (URP 구현/설정에 따라 다름)
11.3 패턴 3: Custom Render Target(오프스크린 렌더)
목표:
- 특정 레이어/오브젝트만 별도 RT에 렌더
- 이후 합성/마스크에 사용
핵심:
- 컬링/드로우 설정(FilteringSettings, DrawingSettings)
- 렌더 타겟 수명 관리(RTHandle/RenderGraph)
RenderGraph에서 오프스크린 렌더를 할 때의 구조적 포인트
- “무엇을 그릴지”는 RendererList(또는 유사 개념)로 캡슐화하는 방향이 안전합니다.
- “어디에 그릴지”는
SetRenderAttachment로 명시합니다. - “무슨 셰이더 패스를 사용할지”는 ShaderLab Pass의
LightMode(또는 ShaderTagId)와 연결됩니다.
이 패턴을 익히면:
- 마스크/ID 버퍼 생성
- 커스텀 쉐도우/특수 뎁스 패스
- 특정 오브젝트만 별도 컬러에 렌더(미니맵/포털/후처리)
같은 기능을 체계적으로 구현할 수 있습니다.
11.4 패턴 4: RenderGraph 기반 멀티 패스(다운샘플 체인)
목표:
- 블러/블룸/피라미드 텍스처 생성
핵심:
- 패스 간 의존성을 handle로 연결
- 임시 텍스처를 여러 단계로 생성/재사용
실전 팁
- 다운샘플/업샘플은 대역폭과 필터링 품질의 트레이드오프입니다.
- 가능하면 RenderGraph가 리소스를 재사용할 수 있도록, 같은 desc를 쓰는 텍스처는 명확히 공유/재사용 구조로 설계하세요.
11.5 패턴 5: “전역 슬롯 ID”를 RenderGraph와 함께 쓰는 경우
RenderGraph가 중심이더라도, 다음 상황에서는 Shader.PropertyToID + SetGlobalTexture가 여전히 유용합니다.
- 셰이더 코드가 “전역 텍스처 이름”을 기반으로 구성되어 있고, 큰 리팩터링이 어렵다
- ShaderGraph 노드에서 특정 전역 텍스처를 읽어야 한다
- 서드파티 셰이더가 특정 이름의 전역 텍스처를 기대한다
이때 원칙:
- RenderGraph에서 만든
TextureHandle의 백킹을 외부로 노출하는 방식(URP/버전에 따라 지원 형태가 다름)을 확인 - Compatibility Mode에서는 임시 RT를 만들고 전역 슬롯에 바인딩하는 레거시 패턴을 쓰되, 수명 관리와 멀티카메라 누수를 반드시 점검
관련: 05. 텍스처/ID/핸들
11.6 패턴 6: Pass Culling에 강한 그래프 연결
목표:
- "생성했는데 실행되지 않는 패스"를 설계 단계에서 줄인다
핵심:
- 출력은 반드시 다음 패스에서 읽히도록 체인을 만든다
- 디버그용 패스도 소비 경로를 임시로 연결해 생존성을 검증한다
체크리스트:
11.7 패턴 7: 멀티 카메라/카메라 스택 안전화
목표:
- Base/Overlay/SceneView가 섞여도 결과가 일관되게 유지된다
핵심:
- 카메라 타입별 적용 조건을
AddRenderPasses에서 명시 - 입력 리소스(Depth/Normals/Post 활성 여부)가 없는 카메라는 early-out
- 전역 슬롯 충돌 가능성이 있으면 로컬 바인딩 우선
실전 팁:
- 카메라 이름/타입을 로그에 같이 출력해 문제 재현 경로를 기록
- "게임 카메라만 적용"을 기본값으로 두고 점진적으로 확장
11.8 패턴 8: 디버깅 루프(Feature 단위)
- Frame Debugger로 패스가 실제 enqueue/실행되는지 확인
- RenderGraph Viewer로 read/write 계약과 resource lifetime 확인
- 입력 리소스 미준비(Depth/Normals/MotionVectors) 시 early-out 경로 확인
- 멀티 카메라에서 전역 상태 충돌 여부 확인
샘플 참고:
samples/Unity6_Rendering_Bible/01_Architecture_and_Pipeline/04_URP_Renderer_Features_Design.mdsamples/Unity6_Rendering_Bible/04_Render_Graph_System/04_RenderGraph_Debugging_and_Culling.md