book/11-renderer-feature-patterns.md

11. Renderer Feature/Pass 실전 패턴 모음

Copy Color, Depth/Normals 기반 이펙트, 오프스크린 렌더, 다운샘플 체인 등 URP Render Feature 패턴을 정리한다

11. Renderer Feature/Pass 실전 패턴 모음(URP)

이 챕터는 “Render Feature로 구현할 수 있는 전형적 기능”들을 패턴으로 정리합니다.

선행: 03. URP 아키텍처, 04. RenderGraph, 05. 텍스처/ID/핸들

11.1 패턴 1: 카메라 컬러 복사(Copy Color)

목표:

  • Opaque 렌더 이후의 컬러 버퍼를 따로 저장
  • 이후 패스(포스트/투명 등)에서 참조

핵심:

  • RenderGraph: CreateTexture + Blit 패스
  • 레거시: _CameraColorTexture 비슷한 슬롯/RTHandle 활용

RenderGraph 구현 체크리스트

  • 어떤 타이밍의 컬러가 필요한가? (Opaque 이후? Transparent 이후?)
  • 출력 텍스처의 포맷/해상도/스케일이 카메라 컬러와 같은가?
  • 결과를 후속 패스가 접근할 수 있도록 어디에 “노출”할 것인가?
    • (A) UniversalResourceData의 activeColor 교체
    • (B) 전역 슬롯(SetGlobalTexture)에 바인딩(필요 시)

11.2 패턴 2: Depth/Normals 기반 이펙트

목표:

  • 윤곽선, SSAO, 스크린 스페이스 효과

핵심:

  • URP가 Depth/Normal 텍스처를 생성하도록 설정
  • 셰이더에서 해당 텍스처를 올바르게 샘플링

실전 체크리스트

  • Requirements(Depth/Normal)가 충족되도록 설정했는가?
    • Full Screen Pass Renderer Feature를 쓴다면 Requirements에서 체크
    • 커스텀 패스라면 URP 문서/소스에 따라 입력 요구를 선언
  • Raw depth를 선형화했는가? (_ZBufferParams 기반)
  • 노말 텍스처가 월드 노말인지 뷰 노말인지 확인했는가? (URP 구현/설정에 따라 다름)

관련: 08. URP HLSL 라이브러리 지도

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 단위)

  1. Frame Debugger로 패스가 실제 enqueue/실행되는지 확인
  2. RenderGraph Viewer로 read/write 계약과 resource lifetime 확인
  3. 입력 리소스 미준비(Depth/Normals/MotionVectors) 시 early-out 경로 확인
  4. 멀티 카메라에서 전역 상태 충돌 여부 확인

샘플 참고:

  • samples/Unity6_Rendering_Bible/01_Architecture_and_Pipeline/04_URP_Renderer_Features_Design.md
  • samples/Unity6_Rendering_Bible/04_Render_Graph_System/04_RenderGraph_Debugging_and_Culling.md