book/16-urp-shaderlibrary-lit-include-chain.md

16. URP ShaderLibrary 실제 맵: Lit 기준 include 체인

Unity 6.3(6000.3) + URP(17.x)에서 Lit.shader를 기준으로 어떤 HLSL 파일/함수/키워드가 어떻게 연결되는지 ‘실제 소스 기반’으로 지도화한다

16. URP ShaderLibrary 실제 맵: Lit 기준 include 체인

이 챕터의 목표는 다음 질문들에 “경로를 잃지 않고” 답할 수 있게 만드는 것입니다.

  • URP Lit.shader는 어떤 패스(LightMode)들로 구성되어 있는가?
  • 각 패스는 어떤 .hlsl을 include하고, 거기서 어떤 엔트리 함수(vertex/fragment)가 정의되는가?
  • TransformObjectToHClip, GetMainLight, UniversalFragmentPBR 같은 함수는 어느 파일에서 오는가?

매우 중요
URP는 패키지 버전이 바뀌면 파일 구성/함수 이름이 조금씩 바뀝니다.
이 문서는 URP Lit를 기준으로 “역할/연결 구조” 를 고정해 이해하도록 돕고, 최종 확인은 로컬 패키지 소스로 하도록 설계합니다.

16.0 정확 레퍼런스(Generated, URP 17.3.0)

이 챕터의 “정확성 앵커(anchor)”는 아래 자동 생성물입니다.

원칙: “정의 위치(파일/라인)”는 generated가 1차 정답입니다.
맥락(왜 그렇게 구현됐나)은 로컬 URP/Core 소스를 열어 읽습니다.

선행:

16.1 먼저 버전을 고정하자(“Unity 6.3”의 실체)

Unity 6.3은 보통 6000.3.* 에디터 버전을 의미하지만, 셰이더 include 체인은 URP 패키지 버전에 의해 결정됩니다.

실무 체크:

  1. Package Manager에서 com.unity.render-pipelines.universal 버전을 확인
  2. 로컬 패키지 소스를 열어서(Packages/ 또는 Library/PackageCache/) 실제 파일을 확인

관련: 01. 큰그림

16.2 Lit.shader는 “패스 묶음”이다(URP 17.3.0: LightMode 9종)

URP Lit.shader는 “Lit 머티리얼”이 파이프라인의 여러 단계에 참여할 수 있도록 여러 ShaderLab Pass의 묶음으로 구성됩니다.

URP 17.3.0의 Lit.shader에는 아래 9개 LightMode Pass가 존재합니다(정확 목록/Include는 book/generated/urp-lit-map.md 참고).

Pass Name LightMode 언제 소비되나(요약)
ForwardLit UniversalForward 기본 Forward 컬러(Forward+ 포함)
GBuffer UniversalGBuffer Deferred 렌더링에서 GBuffer 출력
ShadowCaster ShadowCaster 그림자 맵 렌더링
DepthOnly DepthOnly 카메라 Depth/깊이 프리패스
DepthNormals DepthNormals Depth+Normals 텍스처 생성(SSAO/Outline 기반)
Meta Meta 라이트맵 베이킹용
MotionVectors MotionVectors 오브젝트 모션 벡터(velocity)
XRMotionVectors XRMotionVectors XR 모션 벡터(+스텐실 계약 포함)
Universal2D Universal2D 2D Renderer 호환 패스

이 pass들은 URP의 Render Pass(=C# 파이프라인 단계)가 “특정 LightMode를 가진 ShaderLab Pass”를 찾을 때 선택됩니다.

관련: 09. URP 호환 셰이더 작성

16.3 Lit 기준 “include 체인” 큰 지도

Lit 계열 셰이더의 include는 크게 3층으로 생각하면 안정적입니다.

  1. Core 층(기반): 좌표 변환/플랫폼 매크로/유틸/정의
  2. 기능 층(입력/라이팅/쉐도우/GI): 라이트 접근, BRDF, 그림자 샘플링, 라이트맵/프로브
  3. 패스 층(엔트리): Forward/Depth/Shadow/Meta의 vertex/fragment 엔트리 함수

16.3.1 Mermaid로 보는 체인(개념 지도)

이 그래프는 “어떤 역할이 어디에 연결되는지”를 표현합니다.
정확한 파일명은 URP 버전에서 다를 수 있으니, 그래프를 따라 로컬 패키지에서 확인하세요.

Parse error on line 33:
...ader --> ForwardPass --> LitForward  Li
-----------------------^
Expecting 'SEMI', 'NEWLINE', 'EOF', got 'ARROW_POINT'

이 지도를 기준으로, 함수가 어디서 오는지 추적합니다.

16.4 Pass별 “엔트리 함수”와 주요 책임(URP 17.3.0)

URP 셰이더에서 가장 중요한 것은 “각 Pass가 어떤 엔트리/출력을 책임지는가(=계약)”입니다.

Pass Name LightMode 엔트리(대표) 핵심 책임(요약)
ForwardLit UniversalForward LitPassVertex / LitPassFragment SurfaceData/InputData 구성 → PBR 합성 → Fog/Alpha → SV_Target* 출력
GBuffer UniversalGBuffer LitGBufferPassVertex / LitGBufferPassFragment Deferred용 GBuffer 출력
ShadowCaster ShadowCaster ShadowPassVertex / ShadowPassFragment 그림자 맵 depth 기록(+알파 클립/바이어스)
DepthOnly DepthOnly DepthOnlyVertex / DepthOnlyFragment depth 기록(+알파 클립)
DepthNormals DepthNormals DepthNormalsVertex / DepthNormalsFragment depth+normal 기록(SSAO/outline 기반)
Meta Meta UniversalVertexMeta / UniversalFragmentMetaLit 베이킹용 meta 출력(알베도/에미션 중심)
MotionVectors MotionVectors (ObjectMotionVectors 제공 엔트리) velocity 출력(ColorMask RG)
XRMotionVectors XRMotionVectors (ObjectMotionVectors 제공 엔트리) XR velocity 출력(+스텐실 계약)
Universal2D Universal2D vert / frag(Universal2D) 2D Renderer 호환 컬러 패스

실무 포인트
“완전 호환”은 단순히 ForwardLit만 되는 상태가 아니라, 프로젝트가 실제로 소비하는 LightMode Pass를 제공하는 상태입니다.
계약 전체 표(언제/왜 소비되는가): book/20-urp-pass-tags-and-lightmode-contract.md

관련: 09. URP 호환 셰이더 작성

16.5 Lit Forward(UniversalForward)를 “정확 레퍼런스”로 고정하기

Lit Forward는 URP에서 가장 많이 커스터마이즈되는 영역이므로, 아래 심볼들은 반드시 시그니처/반환값/정의 위치까지 고정해 두는 것을 권장합니다.

원본: book/generated/urp-17.3.0/xref/lit-key-symbols.md

16.5.1 핵심 심볼(반환값/정의 위치)

Symbol Returns Params(요약) Defined-in
TransformObjectToHClip float4 float3 positionOS <CORE>/ShaderLibrary/SpaceTransforms.hlsl:108
LitPassVertex Varyings Attributes input <URP>/Shaders/LitForwardPass.hlsl:158
LitPassFragment void out SV_Target* 출력 <URP>/Shaders/LitForwardPass.hlsl:223
InitializeStandardLitSurfaceData void float2 uv, out SurfaceData <URP>/Shaders/LitInput.hlsl:252
InitializeInputData void Varyings, normalTS, out InputData <URP>/Shaders/LitForwardPass.hlsl:72
UniversalFragmentPBR half4 InputData, SurfaceData <URP>/ShaderLibrary/Lighting.hlsl:282

16.5.2 LitPassFragmenthalf4 return이 아닌 이유: out SV_Target(MRT/Rendering Layers)

URP 17.3.0에서 LitPassFragment는 반환값 대신 SV_Target0(및 조건부 SV_Target1)를 out 파라미터로 출력합니다.

  • 정의: <URP>/Shaders/LitForwardPass.hlsl:223

이 형태는:

  • MRT(렌더 타겟 다중 출력)로 확장 가능한 형태를 유지하고,
  • Rendering Layers 같은 기능이 켜졌을 때 추가 출력을 붙이기 쉽고,
  • “완전 호환” 커스텀 셰이더가 URP 기능과 결합될 가능성을 높입니다.

16.5.3 Lit Forward 호출 흐름(단계 고정)

URP Lit Forward 프래그먼트는 대체로 아래 순서로 구성됩니다(정확 호출 지점은 generated xref로 고정).

  1. InitializeStandardLitSurfaceData — UV/텍스처로 SurfaceData 구성
  2. InitializeInputData — Varyings/normalTS로 InputData 구성
  3. (옵션) Decal/GI/APV 등 주변 기능 결합
  4. UniversalFragmentPBR — 메인/추가 라이트/그림자/GI 합성
  5. MixFog, OutputAlpha 등 후처리 후 SV_Target* 출력
Parse error on line 1:
flowchart TD  A[Lit
^
Expecting 'NEWLINE', 'SPACE', 'GRAPH', got 'ALPHA'

16.5.4 Forward+ 루프 분기(요약)

Forward+에서는 추가 라이트 루프 계약이 달라집니다.

  • GetAdditionalLightsCount()가 0을 반환할 수 있습니다(계약).
    • 정의: <URP>/ShaderLibrary/RealtimeLights.hlsl:271
  • URP는 LIGHT_LOOP_BEGIN/END로 Forward/Forward+ 루프를 동시에 만족시킵니다.
    • 정의: <URP>/ShaderLibrary/RealtimeLights.hlsl:28 / :36

자세한 내용/디버깅 루틴: 07. Forward/Forward+/Lights

16.6 SurfaceData vs InputData: “무엇을 어디에 넣는가”

URP Lit를 이해하는 가장 좋은 기준은 이 두 구조체를 분리해 암기하는 것입니다.

16.6.1 SurfaceData(표면/재질 입력)

SurfaceData는 “머티리얼이 어떤 표면인가”에 대한 정보입니다.

  • 알베도(Base Color/Base Map)
  • 노말(Normal Map)
  • 메탈릭/스무스니스/오클루전/에미션
  • 알파/컷오프

즉, 텍스처 샘플링과 머티리얼 파라미터 정리가 핵심입니다.

16.6.2 InputData(공간/카메라/조명 입력)

InputData는 “그 표면이 씬에서 어디에 있고, 어떤 카메라/조명 조건인지” 정보입니다.

  • positionWS / normalWS / viewDirectionWS
  • shadowCoord
  • fogCoord
  • bakedGI / shadowMask
  • normalizedScreenSpaceUV

즉, 공간/좌표/카메라/그림자/GI 준비가 핵심입니다.

이 분리를 이해하면:

  • “표면 모델을 바꾸고 싶다” → SurfaceData 생성/변형 쪽
  • “라이팅 계산을 바꾸고 싶다” → PBR 함수 또는 라이트 접근 쪽
  • “깊이/스크린 UV가 필요하다” → InputData/코어 유틸 쪽

으로 빠르게 방향을 잡을 수 있습니다.

16.7 “정확 레퍼런스”를 로컬에서 자동 생성하는 방법(추천)

이 책은 “원본(패키지 소스)”을 기준으로 학습하는 것을 목표로 하므로, include/심볼/xref를 자동 추출해 “정확 레퍼런스”를 생성하는 워크플로를 제공합니다.

  • 원클릭 러너: tools/generate-all.ps1
  • 출력 루트: book/generated/ (stable) + book/generated/urp-17.3.0/ (versioned)
  • 생성물 목록/실행법: book/generated/README.md

tools/generate-all.ps1는 다음을 순서대로 수행합니다.

  1. Lit Pass/Include 맵 생성: book/generated/urp-lit-map.md
  2. 심볼 인덱스 생성(함수/구조체/매크로/파일): book/generated/urp-17.3.0/symbols/*
  3. Lit 핵심 심볼 xref 생성: book/generated/urp-17.3.0/xref/lit-key-symbols.md

실행(예시):

POWERSHELL
powershell -ExecutionPolicy Bypass -File tools/generate-all.ps1 -UnityProjectRoot "<YOUR_UNITY_PROJECT_ROOT>"

생성물은 절대 경로를 그대로 노출하지 않고 <URP>, <CORE>로 치환합니다.

참고
개별 실행이 필요하면 tools/generate-urp-lit-map.ps1 같은 단일 스크립트도 사용할 수 있지만,
“문서-레퍼런스 연결”을 유지하려면 원클릭 러너를 기본 루틴으로 권장합니다.

16.8 다음으로 무엇을 보면 좋은가?

16.9 실습 과제(추천)

  1. tools/generate-all.ps1 실행 후 book/generated/urp-lit-map.md를 연다.
  2. ForwardLit (UniversalForward) 섹션에서 include 목록을 본다.
  3. book/generated/urp-17.3.0/xref/lit-key-symbols.md에서 다음을 “정의 위치 → 호출처”로 추적한다.
    • LitPassFragment
    • InitializeStandardLitSurfaceData
    • InitializeInputData
    • UniversalFragmentPBR
  4. Frame Debugger로 “DepthNormals pass가 언제 호출되는지”를 실제 프레임에서 확인한다.