08. URP HLSL library structure map (file/function role)
When trying to “extend code” a URP shader, the quickest sticking points are simple.
- “Where is this function/structure defined?”
- “What functionality does this include provide?”
- “Where do features like Forward+ branch out?”
This chapter aims to make the above questions traceable:
- File role (what category it is)
- Symbol signature (return value/parameter)
- Definition location (file/line)
- Call flow (where the call is made)
Bundle them into one routine.
Precedence: 07. Forward/Forward+/Lights
8.0 Accurate Reference (Generated, URP 17.3.0)
This repository scans local URP/Core sources to generate “accurate references”.
- Lit Pass/Include Map: @@TOK_0_14164784@@
- Function signature index: @@TOK_1_20e1594e@@
- Structure index (including fields): @@TOK_2_11a7626e@@
- Macro index: @@TOK_3_9ecae65e@@
- Lit core symbol xref: @@TOK_4_8394c928@@
We recommend looking at Generated first (confirming the location of the definition) → opening the source and reading the context.
8.1 Where is the URP/Core source? (embedded vs cache)
In a Unity project, package sources usually reside in one of two places:
- embedded:
Packages/<packageName>/... - cache:
Library/PackageCache/<packageName>@<version>/...
Scripts in this repository will take precedence over embedded, and if not found, will look in the cache.
- Path analysis utility:
tools/_lib/UnityPackageResolve.ps1
In the Generated document, <URP>, <CORE> is substituted for absolute paths (prevention of path exposure + reproducibility).
8.2 Reading URP HLSL as “categories”: 5 layers
The method of memorizing file names breaks down the moment the URP version changes. Instead, it is more stable if you classify it into the five layers below.
- Core: Platform/Precision/Input constants/Basic macro/Coordinate conversion
- Input (value provided by engine): Camera/Screen/Time/Texture declaration/Frame constant
- Surface (Surface/Material input): BaseMap/Normal/Mask, etc. sampling → SurfaceData configuration
- Lighting/Shadows/GI(Lighting/Shadows/Indirect Lighting): Light access, BRDF, shadow, lightmap/probe
- Pass (Entry/Contract): Step-by-step entry such as Forward/GBuffer/DepthOnly/DepthNormals/Meta/MotionVectors
Deciding first “Which layer is the symbol I’m looking for” will greatly speed up your search.
8.3 What does Core.hlsl bind? (actual include chain)
In URP, Core.hlsl is effectively the “root (include entry) of the URP shader world”.
Particularly important points from Core.hlsl in URP 17.3.0:
_CLUSTER_LIGHT_LOOP→ Convert toUSE_CLUSTER_LIGHT_LOOP(Forward+ loop switch)- Pull SRP Core (common) include (
Common.hlsl,Packing.hlsl, etc.) - Include
Input.hlslof URP (based on global constants/structures/utils)
If you remember these 3 things:
- “Where does Forward+ turn on?”
- “Why do transformation functions like TransformObjectToHClip come from Core?”
- “Where should structures like InputData/SurfaceData go?”
You can fast track it.
Related symbols (see generated for location of definition):
USE_CLUSTER_LIGHT_LOOP:<URP>/ShaderLibrary/Core.hlsl:14/:16_CLUSTER_LIGHT_LOOP:<URP>/ShaderLibrary/ForwardPlusKeyword.deprecated.hlsl:20, etc.
8.4 “Routine for finding symbols” (combined search/reference)
The fastest routine for URP HLSL navigation is below.
8.4.1 Step 1: Grab the Pass root file
Example: If Lit Forward
<URP>/Shaders/LitForwardPass.hlsl<URP>/Shaders/LitInput.hlslThe exact include list is at @@TOK_0_14164784@@.
8.4.2 Step 2: Fix “definition location (file/line)” in generated
- Function signature (return value/parameter): @@TOK_1_20e1594e@@
- Structure field: @@TOK_2_11a7626e@@
- Representative reference (xref): @@TOK_3_8394c928@@
Example (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 Step 3: Read “context” from local sources
Check which #if the definition is wrapped in, which global constants/buffers it reads, and which macro it branches to.
8.5 File Role Map (URP 17.3.0, Learning Core only)
The table below is a map linking “File → Provided symbol (representative) → Where to use”.
See @@TOK_14_9379ac20@@ for a full list of symbols.
| File | Role | Representative symbol (example) | Representative consumers |
|---|---|---|---|
<URP>/ShaderLibrary/Core.hlsl |
root include/platform/forward+ switch | USE_CLUSTER_LIGHT_LOOP, TEXTURE2D_X, etc. |
Almost all URP shaders |
<CORE>/ShaderLibrary/SpaceTransforms.hlsl |
coordinate transformation | TransformObjectToHClip |
Lit/Unlit/Depth* Overall |
<URP>/ShaderLibrary/Input.hlsl |
InputData/global constant based | InputData struct etc. |
LitForward, Lighting |
<URP>/ShaderLibrary/RealtimeLights.hlsl |
Light abstraction/light loop | Light, GetMainLight, GetAdditionalLight, LIGHT_LOOP_BEGIN/END |
Lighting.hlsl, LitForward |
<URP>/ShaderLibrary/Lighting.hlsl |
PBR/Lighting Composite | UniversalFragmentPBR |
LitForwardPass |
<URP>/ShaderLibrary/Shadows.hlsl |
Shadow Sampling | TransformWorldToShadowCoord etc. |
Lighting/RealtimesLights |
<URP>/Shaders/LitForwardPass.hlsl |
Forward entry/input initialization | LitPassVertex, LitPassFragment, InitializeInputData |
Lit.shader(UniversalForward) |
<URP>/Shaders/LitInput.hlsl |
Enter Lit Surface | InitializeStandardLitSurfaceData |
LitForward/GBuffer/Meta |
<URP>/Shaders/LitGBufferPass.hlsl |
Deferred entry | LitGBufferPassVertex/Fragment |
Lit.shader(UniversalGBuffer) |
<URP>/ShaderLibrary/ObjectMotionVectors.hlsl |
MotionVectors Entry/Contract | (motion vector entry) | Lit.shader(MotionVectors/XRMotionVectors) |
8.6 Depth/Normals Texture: Step 4: “Create → Declare → Sampling → Linearize”
Screen-based effects that require Depth/Normals (Outline/SSAO/SSR types) cannot be solved by simply calling SampleSceneDepth.
- Generation: Is the URP pipeline actually creating Depth/Normals textures?
- Declaration: Is the shader using the Declare/sampling include provided by URP?
- Sampling: Are you sampling correctly in UV/RenderScale/XR?
- Linearization: Convert raw depth to LinearEyeDepth with
_ZBufferParams?
Concept code (example):
float raw = SampleSceneDepth(uv);
float eye = LinearEyeDepth(raw, _ZBufferParams);
The exact include/function name may vary depending on the URP version.
The key is to carry out “4 steps (creation → declaration → sampling → linearization)” as a checklist.
8.7 Search Recipe (Generated + rg)
Find quickly in 8.7.1 generated
- Function signature: @@TOK_0_20e1594e@@
- Structure/Field: @@TOK_1_11a7626e@@
- Key symbol xref: @@TOK_2_8394c928@@
8.7.2 Finding directly from the source (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
Further reading (official/authoritative sources)
- URP Shader Method (Transformations): https://docs.unity3d.com/6000.3/Documentation/Manual/urp/use-built-in-shader-methods-transformations.html