Use shadows in a custom URP shader
Get shadow data from lights in the scene, and calculate shadows.
Read time 3 minutesLast updated 22 days ago
To use shadows in a custom Universal Render Pipeline (URP) shader, follow these steps:
- Add inside the
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"in your shader file. TheHLSLPROGRAMfile imports theCore.hlslandShadows.hlslfiles.RealtimeLights.hlsl - Use any of the methods from the following sections.
Get a position in shadow space
Use these methods to convert positions to shadow map positions.
Method | Syntax | Description |
|---|---|---|
| | Converts a vertex position into shadow space. Refer to Transform positions in a custom URP shader for information on the |
| | Converts a position in world space to shadow space. |
Calculate shadows
The following methods calculate shadows using shadow maps. To use these methods, follow these steps first:
- Make sure there are objects in your scene that have a shader pass, for example objects that use the
ShadowCastershader.Universal Render Pipeline/Lit - Add to your shader, so it can access the shadow map for the main light.
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN - Add to your shader, so it can access the shadow maps for additional lights.
#pragma multi_compile _ _ADDITIONAL_LIGHT_SHADOWS
Method | Syntax | Description |
|---|---|---|
| | Returns the main light in the scene, with a |
| | Returns the index of the shadow cascade at the position in world space. Refer to Shadow cascades for more information. |
| | Returns the shadow value from the main shadow map at the coordinates. Refer to Shadow mapping for more information. |
| | Returns the shadow value from the additional light shadow map at the position in world space. |
| | Returns the amount to fade the shadow from the main light, based on the distance between the position and the camera. |
| | Returns the amount to fade the shadow from additional lights, based on the distance between the position and the camera. |
| | Adds shadow bias to the position in world space. Refer to Shadow troubleshooting for more information. |
Example
This code example is a simplified example of drawing shadows onto a surface. It might not work correctly with more than one shadow cascade.
To generate shadows, make sure there are objects in your scene that have a shader pass, for example objects that use the shader.
ShadowCasterUniversal Render Pipeline/LitShader "Custom/SimpleShadows"{ SubShader { Tags { "RenderType" = "AlphaTest" "RenderPipeline" = "UniversalPipeline" } Pass { HLSLPROGRAM #pragma vertex vert #pragma fragment frag #pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl" struct Attributes { float4 positionOS : POSITION; }; struct Varyings { float4 positionCS : SV_POSITION; float4 shadowCoords : TEXCOORD3; }; Varyings vert(Attributes IN) { Varyings OUT; OUT.positionCS = TransformObjectToHClip(IN.positionOS.xyz); // Get the VertexPositionInputs for the vertex position VertexPositionInputs positions = GetVertexPositionInputs(IN.positionOS.xyz); // Convert the vertex position to a position on the shadow map float4 shadowCoordinates = GetShadowCoord(positions); // Pass the shadow coordinates to the fragment shader OUT.shadowCoords = shadowCoordinates; return OUT; } half4 frag(Varyings IN) : SV_Target { // Get the value from the shadow map at the shadow coordinates half shadowAmount = MainLightRealtimeShadow(IN.shadowCoords); // Set the fragment color to the shadow value return shadowAmount; } ENDHLSL } }}