Shadow Caster

 https://cyangamedev.wordpress.com/2020/06/05/urp-shader-code/10/


Writing Shader Code for the Universal RP

ShadowCaster & DepthOnly Passes

If we want the shader to cast shadows, it needs a pass with the tag “LightMode”=”ShadowCaster”. This can be done on both Unlit and Lit shaders, but be aware that while they will cast shadows – they won’t receive shadows unless you handle that in the UniversalForward pass.

Shaders should also include a pass tagged with “LightMode”=”DepthOnly”. This pass is very similar to the ShadowCaster, but without the shadow bias offsets. I’m not completely sure what the DepthOnly pass is used for in the URP. The Scene View seems to use it when rendering the depth texture (used by the Scene Depth node in shadergraph), while the Game View depth texture seems to work fine without this pass. There may be other things like custom render features (for the forward renderer) that rely on the DepthOnly pass though.

Like with all the passes in the shader, they have to share the same UnityPerMaterial CBUFFER for the shader to be compatible with the SRP Batcher. In previous sections of this post, we put the buffer inside the HLSLINCLUDE so that it is automatically used for every pass in the shader.

Except when using UsePass, which was discussed back in the Shaderlab section. Although we could use the shadow caster from other shaders, e.g. UsePass “Universal Render Pipeline/Lit/ShadowCaster”, the SRP Batcher compatibility might be lost as the CBUFFER used in that shader is probably different.

Instead you should define these passes yourself, but as a slight workaround we can do the following :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
Pass {
    Name "ShadowCaster"
    Tags { "LightMode"="ShadowCaster" }
 
    ZWrite On
    ZTest LEqual
 
    HLSLPROGRAM
    // Required to compile gles 2.0 with standard srp library
    #pragma prefer_hlslcc gles
    #pragma exclude_renderers d3d11_9x gles
    //#pragma target 4.5
 
    // Material Keywords
    #pragma shader_feature _ALPHATEST_ON
    #pragma shader_feature _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
 
    // GPU Instancing
    #pragma multi_compile_instancing
    #pragma multi_compile _ DOTS_INSTANCING_ON
             
    #pragma vertex ShadowPassVertex
    #pragma fragment ShadowPassFragment
     
    #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/CommonMaterial.hlsl"
    #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceInput.hlsl"
    #include "Packages/com.unity.render-pipelines.universal/Shaders/ShadowCasterPass.hlsl"
 
    ENDHLSL
}

Using the ShadowCasterPass that Unity uses for their URP shaders means it’s a bit easier to define the pass, however it requires using the _BaseMap, _BaseColor and _Cutoff properties, and we need to add them to our UnityPerMaterial CBUFFER too.

The fragment function in the shadow caster just returns 0 where a shadow needs to be, and discards the pixel where there shouldn’t be any shadows (note, that clipping only happens if the _ALPHATEST_ON keyword is enabled), you can take a look at the code by clicking the link above.

If our regular shader pass also does vertex displacement, this needs to be added to the ShadowCaster pass

댓글

이 블로그의 인기 게시물

About AActor!!! "UObject" has no member "BeginPlay"

UNREAL Android build information

Shader informations nice blog ~ ~