22. URP Lit Call Flow & Edit Points (URP 17.3.0)
This chapter is a practical guide to end “I studied URP Lit, but I don’t know where to fix it.”
- Lit Forward (UniversalForward) Fixes the actual flow of the fragment to the “correct reference” and
- Where to put customization so as not to break compatibility (=edit points)
- What has a high risk of breaking immediately when touched (=risk points)?
We organize it step by step.
22.0 Accurate Reference (Generated)
The symbols/definitions/references in this chapter refer to the document generated below as the primary source.
- Lit core symbol xref: @@TOK_0_8394c928@@
- Function signature: @@TOK_1_20e1594e@@
- Structure/Field: @@TOK_2_11a7626e@@
- Lit Pass/Include Map: @@TOK_3_14164784@@
22.1 Fixed Lit Forward entry (definition location/signature)
As of URP 17.3.0:
LitPassVertex- Definition:
<URP>/Shaders/LitForwardPass.hlsl:158 - Signature:
Varyings LitPassVertex(Attributes input)
- Definition:
LitPassFragment- Definition:
<URP>/Shaders/LitForwardPass.hlsl:223 - Core:
void+out SV_Target*output
- Definition:
Output structure (summary) of LitPassFragment:
void LitPassFragment(
Varyings input,
out half4 outColor : SV_Target0
// + optional: outRenderingLayers : SV_Target1
)
Why not return half4?
For extending features such as MRT/Rendering Layers, the “keep output contract as out parameter” structure is safer.
Related: 16. URP Lit include 체인 맵
22.2 Actual call flow of Lit Forward (URP 17.3.0)
The core flow of URP 17.3.0 LitForwardPass is summarized below (exact call points are in xref):
- (Optional) Parallax / LODFade
- Configure
SurfaceDatawithInitializeStandardLitSurfaceData - Configure
InputDatawithInitializeInputData - (Optional) Decal(DBuffer)
- Prepare baked GI with
InitializeBakedGIDataetc. - Lighting synthesis with
UniversalFragmentPBR - Output after Fog/Alpha processing
Core function definition location (URP 17.3.0):
| Symbol | Returns | Defined-in |
|---|---|---|
InitializeStandardLitSurfaceData |
void |
<URP>/Shaders/LitInput.hlsl:252 |
InitializeInputData |
void |
<URP>/Shaders/LitForwardPass.hlsl:72 |
ApplyDecalToSurfaceData |
void |
<URP>/ShaderLibrary/DBuffer.hlsl:191 |
InitializeBakedGIData |
void |
<URP>/Shaders/LitForwardPass.hlsl:132 |
UniversalFragmentPBR |
half4 |
<URP>/ShaderLibrary/Lighting.hlsl:282 |
MixFog |
half3/float3 |
<URP>/ShaderLibrary/ShaderVariablesFunctions.hlsl:513 |
OutputAlpha |
half |
<URP>/ShaderLibrary/ShaderVariablesFunctions.hlsl:239 |
Fix the flow with Mermaid:
Parse error on line 1: flowchart TD A[Lit ^ Expecting 'NEWLINE', 'SPACE', 'GRAPH', got 'ALPHA'
22.3 Edit Points (Safe Customization Points) — “Where can I change something to make it less broken?”
URP Lit is tightly coupled with surrounding features (Forward+/Decal/Rendering Layers/GI/ShadowMixing, etc.). Therefore, the safest way to “customize while maintaining compatibility” is to adjust internal values while maintaining the light loop/pass contract.
22.3.1 Edit Point A: Adjust SurfaceData (most secure)
Target:
surfaceData.albedo,surfaceData.normalTS,surfaceData.smoothness,surfaceData.emission, etc.
Advantages:
- Material model can be changed while maintaining Pass contract/Forward+ loop/Shadow/GI coupling
Risk:
- Low (however, when combined with
alpha/_ALPHATEST_ON, ShadowCaster/DepthOnly needs to be checked)
Verification:
- Check if ShadowCaster/DepthOnly/DepthNormals are normal together in Frame Debugger
- Check whether SRP Batcher (material constant) is maintained (Chapter 09)
22.3.2 Edit Point B: Adjust InputData (medium difficulty)
Target:
inputData.normalWS,inputData.viewDirectionWS,inputData.shadowCoord,inputData.normalizedScreenSpaceUV, etc.
Advantages:
- Easy to add view/space based effects (e.g. custom fresnel, view-dependent term)
Risk:
- medium
- In particular, messing with
normalizedScreenSpaceUVmay break the Forward+ cluster loop.
- In particular, messing with
Verification:
- Check if additional light is normal in Forward+ ON (Chapter 07)
22.3.3 Edit Point C: UniversalFragmentPBR Adjust color before/after (only when the purpose is clear)
Target:
- Post-process the
half4 color = UniversalFragmentPBR(...)results (rim,toon,custom tone) or - Expression for normalizing PBR input (e.g. roughness clamp)
Risk:
- Medium to high
- Physics-based assumptions may be broken and unexpected results may occur when combined with Debug Display/Decal/Rendering Layers.
Verification:
- Check with Debug Display/Post Processing/Decal turned on
22.3.4 Risk Point: “Implement additional light loops yourself” (most risky)
In Forward+, there is a contract that GetAdditionalLightsCount() can be 0.
- Definition:
<URP>/ShaderLibrary/RealtimeLights.hlsl:271
So if you need to implement additional light loops yourself, at least use URP's macros.
uint count = GetAdditionalLightsCount();
LIGHT_LOOP_BEGIN(count)
Light light = GetAdditionalLight(lightIndex, inputData, shadowMask, aoFactor);
// accumulate...
LIGHT_LOOP_END
More details: 07. Forward/Forward+/Lights
22.4 Edit Point Matrix (Summary)
| change target | Recommended points | Compatibility Risk | Be sure to check together |
|---|---|---|---|
| Change material model (albedo/roughness/normal) | SurfaceData Edit |
low | ShadowCaster/DepthOnly/DepthNormals |
| Add view dependent terms (rim/fresnel) | InputData/PBR before and after |
middle | Forward+ / XR / Fog |
| Lighting Model (BRDF) Replacement | UniversalFragmentPBR Path |
Medium to high | Additional Light Loops/Shadows/GI |
| Light Roof Self Replacement | Direct implementation | High | LIGHT_LOOP_*, Forward+ Contract |
| Change Pass/Tag/Output | ShaderLab Edit | very high | LightMode Consumption (Chapter 20) |
22.5 Verification routine (required)
- Fix the definition position as generated: @@TOK_4_8394c928@@
- Frame Debugger: Check with which LightMode Pass my object is drawn.
- Compare Forward+ ON/OFF: Check whether the additional light is normal in both modes
- DepthNormals/MotionVectors: If the project has functions such as SSAO/TAA turned on, check whether the pass is actually consumed.
Troubleshooting Playbook: @@TOK_5_a2e9de9a@@