08. URP HLSL 라이브러리 구조 지도(파일/함수 역할)
URP 셰이더를 “코드로 확장”하려고 할 때 가장 빨리 막히는 지점은 단순합니다.
- “이 함수/구조체는 어디에서 정의되나?”
- “이 include는 무슨 기능을 제공하나?”
- “Forward+ 같은 기능은 어디에서 분기되나?”
이 챕터는 위 질문을 검색 가능하게(Traceable) 만들기 위해:
- 파일 역할(어떤 범주인가)
- 심볼 시그니처(반환값/파라미터)
- 정의 위치(파일/라인)
- 호출 흐름(어디에서 호출되나)
를 하나의 루틴으로 묶습니다.
8.0 정확 레퍼런스(Generated, URP 17.3.0)
이 저장소는 로컬 URP/Core 소스를 스캔해서 “정확 레퍼런스”를 생성합니다.
- Lit Pass/Include 맵:
book/generated/urp-lit-map.md - 함수 시그니처 인덱스:
book/generated/urp-17.3.0/symbols/functions.md - 구조체 인덱스(필드 포함):
book/generated/urp-17.3.0/symbols/structs.md - 매크로 인덱스:
book/generated/urp-17.3.0/symbols/macros.md - Lit 핵심 심볼 xref:
book/generated/urp-17.3.0/xref/lit-key-symbols.md
Generated를 먼저 보고(정의 위치 확정) → 소스를 열어 맥락을 읽는 순서를 추천합니다.
8.1 URP/Core 소스는 어디에 있나? (embedded vs cache)
Unity 프로젝트에서 패키지 소스는 보통 두 군데 중 하나에 있습니다.
- embedded:
Packages/<packageName>/... - cache:
Library/PackageCache/<packageName>@<version>/...
이 저장소의 스크립트는 embedded를 우선하고, 없으면 cache를 찾습니다.
- 경로 해석 유틸:
tools/_lib/UnityPackageResolve.ps1
Generated 문서에서는 절대 경로 대신 <URP>, <CORE>로 치환해 기록합니다(경로 노출 방지 + 재현성).
8.2 URP HLSL을 “범주”로 읽기: 5개 레이어
파일명을 외우는 방식은 URP 버전이 바뀌는 순간 무너집니다. 대신 아래 5개 레이어로 분류하면 안정적입니다.
- Core(기반): 플랫폼/정밀도/입력 상수/기본 매크로/좌표 변환
- Input(엔진 제공 값): 카메라/스크린/시간/텍스처 선언/프레임 상수
- Surface(표면/재질 입력): BaseMap/Normal/Mask 등 샘플링 → SurfaceData 구성
- Lighting/Shadows/GI(조명/그림자/간접광): Light 접근, BRDF, 쉐도우, 라이트맵/프로브
- Pass(엔트리/계약): Forward/GBuffer/DepthOnly/DepthNormals/Meta/MotionVectors 등 단계별 엔트리
“내가 찾는 심볼이 어느 레이어인가?”를 먼저 결정하면 탐색 속도가 크게 올라갑니다.
8.3 Core.hlsl가 무엇을 묶나? (실제 include 체인)
URP에서 Core.hlsl은 사실상 “URP 셰이더 세계의 루트(include entry)”입니다.
URP 17.3.0의 Core.hlsl 앞부분에서 특히 중요한 포인트:
_CLUSTER_LIGHT_LOOP→USE_CLUSTER_LIGHT_LOOP로 변환(Forward+ 루프 스위치)- SRP Core(공통) include를 끌어옴(
Common.hlsl,Packing.hlsl등) - URP의
Input.hlsl을 include(전역 상수/구조체/유틸의 기반)
이 3개를 기억하면:
- “Forward+가 어디서 켜지나?”
- “TransformObjectToHClip 같은 변환 함수는 왜 Core에서 오나?”
- “InputData/SurfaceData 같은 구조체는 어디를 따라가야 하나?”
를 빠르게 추적할 수 있습니다.
관련 심볼(정의 위치는 generated 참고):
USE_CLUSTER_LIGHT_LOOP:<URP>/ShaderLibrary/Core.hlsl:14/:16_CLUSTER_LIGHT_LOOP:<URP>/ShaderLibrary/ForwardPlusKeyword.deprecated.hlsl:20등
8.4 “심볼을 찾는 루틴”(검색/레퍼런스 결합)
URP HLSL 탐색에서 가장 빠른 루틴은 아래입니다.
8.4.1 1단계: Pass 루트 파일을 잡는다
예: Lit Forward라면
<URP>/Shaders/LitForwardPass.hlsl<URP>/Shaders/LitInput.hlsl
정확 include 목록은 book/generated/urp-lit-map.md에 있습니다.
8.4.2 2단계: generated에서 “정의 위치(파일/라인)”를 고정한다
- 함수 시그니처(반환값/파라미터):
book/generated/urp-17.3.0/symbols/functions.md - 구조체 필드:
book/generated/urp-17.3.0/symbols/structs.md - 대표 참조(xref):
book/generated/urp-17.3.0/xref/lit-key-symbols.md
예시(URP 17.3.0):
| Symbol | Returns | Defined-in |
|---|---|---|
TransformObjectToHClip |
float4 |
<CORE>/ShaderLibrary/SpaceTransforms.hlsl:108 |
GetMainLight |
Light |
<URP>/ShaderLibrary/RealtimeLights.hlsl |
UniversalFragmentPBR |
half4 |
<URP>/ShaderLibrary/Lighting.hlsl:282 |
8.4.3 3단계: 로컬 소스에서 “맥락”을 읽는다
정의가 어떤 #if에 감싸져 있는지, 어떤 전역 상수/버퍼를 읽는지, 어떤 매크로로 분기하는지를 확인합니다.
8.5 파일 역할 지도(URP 17.3.0, 학습 핵심만)
아래 표는 “파일 → 제공 심볼(대표) → 어디서 쓰나”를 연결한 지도입니다.
전체 심볼 목록은 book/generated/urp-17.3.0/symbols/files.md를 보세요.
| File | 역할 | 대표 심볼(예시) | 대표 소비처 |
|---|---|---|---|
<URP>/ShaderLibrary/Core.hlsl |
루트 include/플랫폼/Forward+ 스위치 | USE_CLUSTER_LIGHT_LOOP, TEXTURE2D_X 등 |
거의 모든 URP 셰이더 |
<CORE>/ShaderLibrary/SpaceTransforms.hlsl |
좌표 변환 | TransformObjectToHClip |
Lit/Unlit/Depth* 전반 |
<URP>/ShaderLibrary/Input.hlsl |
InputData/전역 상수 기반 | InputData struct 등 |
LitForward, Lighting |
<URP>/ShaderLibrary/RealtimeLights.hlsl |
Light abstraction/라이트 루프 | Light, GetMainLight, GetAdditionalLight, LIGHT_LOOP_BEGIN/END |
Lighting.hlsl, LitForward |
<URP>/ShaderLibrary/Lighting.hlsl |
PBR/조명 합성 | UniversalFragmentPBR |
LitForwardPass |
<URP>/ShaderLibrary/Shadows.hlsl |
쉐도우 샘플링 | TransformWorldToShadowCoord 등 |
Lighting/RealtimesLights |
<URP>/Shaders/LitForwardPass.hlsl |
Forward 엔트리/입력 초기화 | LitPassVertex, LitPassFragment, InitializeInputData |
Lit.shader(UniversalForward) |
<URP>/Shaders/LitInput.hlsl |
Lit 표면 입력 | InitializeStandardLitSurfaceData |
LitForward/GBuffer/Meta |
<URP>/Shaders/LitGBufferPass.hlsl |
Deferred 엔트리 | LitGBufferPassVertex/Fragment |
Lit.shader(UniversalGBuffer) |
<URP>/ShaderLibrary/ObjectMotionVectors.hlsl |
MotionVectors 엔트리/계약 | (motion vector entry) | Lit.shader(MotionVectors/XRMotionVectors) |
8.6 Depth/Normals 텍스처: “생성 → 선언 → 샘플링 → 선형화” 4단계
Depth/Normals가 필요한 화면 기반 효과(Outline/SSAO/SSR류)는 단순히 SampleSceneDepth를 호출하는 것만으로 해결되지 않습니다.
- 생성: URP 파이프라인이 Depth/Normals 텍스처를 실제로 만들고 있는가?
- 선언: 셰이더에서 URP가 제공하는 Declare/샘플링 include를 사용하고 있는가?
- 샘플링: UV/렌더스케일/XR에서 올바르게 샘플링하는가?
- 선형화: raw depth를
_ZBufferParams로 LinearEyeDepth로 변환하는가?
개념 코드(예시):
float raw = SampleSceneDepth(uv);
float eye = LinearEyeDepth(raw, _ZBufferParams);
정확한 include/함수명은 URP 버전에 따라 다를 수 있습니다.
“4단계(생성→선언→샘플링→선형화)”를 체크리스트로 들고 가는 게 핵심입니다.
8.7 검색 레시피(Generated + rg)
8.7.1 generated에서 빠르게 찾기
- 함수 시그니처:
book/generated/urp-17.3.0/symbols/functions.md - 구조체/필드:
book/generated/urp-17.3.0/symbols/structs.md - 키 심볼 xref:
book/generated/urp-17.3.0/xref/lit-key-symbols.md
8.7.2 소스에서 직접 찾기(rg)
rg -n "float4\\s+TransformObjectToHClip\\(" Packages/com.unity.render-pipelines.core/ShaderLibrary/SpaceTransforms.hlsl
rg -n "int\\s+GetAdditionalLightsCount\\(" Packages/com.unity.render-pipelines.universal/ShaderLibrary/RealtimeLights.hlsl
rg -n "LIGHT_LOOP_BEGIN" Packages/com.unity.render-pipelines.universal/ShaderLibrary/RealtimeLights.hlsl
rg -n "UniversalFragmentPBR\\(" Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl
추가 읽을거리(공식/권위 자료)
- URP 셰이더 메서드(Transformations): https://docs.unity3d.com/6000.3/Documentation/Manual/urp/use-built-in-shader-methods-transformations.html