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)”는 아래 자동 생성물입니다.
- Lit Pass/Include 맵(Stable):
book/generated/urp-lit-map.md - Lit Pass/Include 맵(Versioned):
book/generated/urp-17.3.0/urp-lit-map.md - Lit 핵심 심볼 xref(정의/대표 참조):
book/generated/urp-17.3.0/xref/lit-key-symbols.md - 함수 시그니처 인덱스:
book/generated/urp-17.3.0/symbols/functions.md - 구조체 인덱스(필드 목록 포함):
book/generated/urp-17.3.0/symbols/structs.md
원칙: “정의 위치(파일/라인)”는 generated가 1차 정답입니다.
맥락(왜 그렇게 구현됐나)은 로컬 URP/Core 소스를 열어 읽습니다.
선행:
16.1 먼저 버전을 고정하자(“Unity 6.3”의 실체)
Unity 6.3은 보통 6000.3.* 에디터 버전을 의미하지만, 셰이더 include 체인은 URP 패키지 버전에 의해 결정됩니다.
실무 체크:
- Package Manager에서
com.unity.render-pipelines.universal버전을 확인 - 로컬 패키지 소스를 열어서(
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”를 찾을 때 선택됩니다.
16.3 Lit 기준 “include 체인” 큰 지도
Lit 계열 셰이더의 include는 크게 3층으로 생각하면 안정적입니다.
- Core 층(기반): 좌표 변환/플랫폼 매크로/유틸/정의
- 기능 층(입력/라이팅/쉐도우/GI): 라이트 접근, BRDF, 그림자 샘플링, 라이트맵/프로브
- 패스 층(엔트리): 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
16.5 Lit Forward(UniversalForward)를 “정확 레퍼런스”로 고정하기
Lit Forward는 URP에서 가장 많이 커스터마이즈되는 영역이므로, 아래 심볼들은 반드시 시그니처/반환값/정의 위치까지 고정해 두는 것을 권장합니다.
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 LitPassFragment가 half4 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로 고정).
InitializeStandardLitSurfaceData— UV/텍스처로 SurfaceData 구성InitializeInputData— Varyings/normalTS로 InputData 구성- (옵션) Decal/GI/APV 등 주변 기능 결합
UniversalFragmentPBR— 메인/추가 라이트/그림자/GI 합성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는 다음을 순서대로 수행합니다.
- Lit Pass/Include 맵 생성:
book/generated/urp-lit-map.md - 심볼 인덱스 생성(함수/구조체/매크로/파일):
book/generated/urp-17.3.0/symbols/* - Lit 핵심 심볼 xref 생성:
book/generated/urp-17.3.0/xref/lit-key-symbols.md
실행(예시):
powershell -ExecutionPolicy Bypass -File tools/generate-all.ps1 -UnityProjectRoot "<YOUR_UNITY_PROJECT_ROOT>"
생성물은 절대 경로를 그대로 노출하지 않고 <URP>, <CORE>로 치환합니다.
참고
개별 실행이 필요하면tools/generate-urp-lit-map.ps1같은 단일 스크립트도 사용할 수 있지만,
“문서-레퍼런스 연결”을 유지하려면 원클릭 러너를 기본 루틴으로 권장합니다.
16.8 다음으로 무엇을 보면 좋은가?
- “이 include/패스 구조를 그대로 반영한 템플릿”은: 18. 완전 호환 Pass 템플릿
- “Compute/UAV 패턴으로 SSAO/SSR류를 만들고 싶다면”은: 17. RenderGraph Compute/UAV 패턴
16.9 실습 과제(추천)
tools/generate-all.ps1실행 후book/generated/urp-lit-map.md를 연다.ForwardLit (UniversalForward)섹션에서 include 목록을 본다.book/generated/urp-17.3.0/xref/lit-key-symbols.md에서 다음을 “정의 위치 → 호출처”로 추적한다.LitPassFragmentInitializeStandardLitSurfaceDataInitializeInputDataUniversalFragmentPBR
- Frame Debugger로 “DepthNormals pass가 언제 호출되는지”를 실제 프레임에서 확인한다.