Search Unity

Question About the meaning of URP Lit shader passes.

Discussion in 'Universal Render Pipeline' started by GiorgioK, Apr 18, 2023.

  1. GiorgioK

    GiorgioK

    Joined:
    Oct 20, 2021
    Posts:
    34
    I am using Unity 2021.3.21f1 and URP 12.1.10
    I'm writing my own URP Lit shader based on the standard URP Lit shader.
    The standard URP Lit shader has the following passes: UniversalForward, ShadowCaster, UniversalGBuffer, DepthOnly, DepthNormals, Meta, Universal2D.

    The question is: what are these passes and in what cases are they used in Unity?
    I'm trying to figure out which passages I need right now and which ones I don't yet.

    1) With the UniversalForward pass, everything is clear - if it does not exist, then the 3D object will not be drawn at all.

    2) ShadowCaster pass. It is also clear here - if it is not there, then the 3D object will not cast a shadow.

    3) UniversalGBuffer pass. I did not understand why it is needed, although I read this https://docs.unity3d.com/Packages/c...nual/urp-shaders/urp-shaderlab-pass-tags.html

    4) DepthOnly pass. I don't understand why it is needed. If you remove it, the whole scene is drawn correctly, there are no problems with objects overlapping. The only difference I've noticed is that without this pass in the Unity editor, the grid always overlays on top of objects, even if they're above it.

    5) DepthNormals pass. If I understood correctly from the help, then this pass is needed to create the _CameraNormalsTexture texture, which is used to create post-processing effects (Fog, Depth of Field, etc.) ?

    6) Meta pass. The help says that it is needed for the baked light map. But if you remove it, then the light baking still works and at about the same speed. So why is it needed?

    7) Universal2D pass. I don't understand why it is needed. Without it, 2D objects are rendered normally. So why is it needed?
     
    DevDunk likes this.
  2. wwWwwwW1

    wwWwwwW1

    Joined:
    Oct 31, 2021
    Posts:
    769
    Hi, I can provide my understanding to these shader passes.

    UniversalGBuffer:
    This pass is used to output object's surface data (albedo, metallic, ...) to several render textures that are used by URP Deferred rendering path.
    DepthOnly:
    This pass is used to output depth to depth render target ("_CameraDepthTexture" or "_CameraDepthAttachment" when Depth Priming is enabled ).

    Although scene depth should be ready after "UniversalForward" pass, but some effects (like SSAO) that requires accessing scene depth are applied before or during "UniversalForward". So we need to render objects' depth before rendering them. (Depth Prepass)

    It's possible but we don't want to reuse "UniversalForward" pass (it calculates lighting) to output depth because it's more performance expensive.​

    DepthNormals:
    This pass is used to output depth to depth render target and world space normals to color render target ("_CameraNormalsTexture").

    Some effects (like SSAO) need to sample scene normals and there's no GBuffers in Forward rendering path.
    Meta:
    This pass is similar to GBuffer pass but it outputs surface data (albedo, metallic, ...) to "lightmaps" (I think). Without this pass, Unity's lightmapper cannot know the object's surface data and won't bake lightmaps for it.

    You can try applying a shader that doesn't have a meta pass to an object (contribute GI set to static) and bake lightmaps for it.
    Universal2D:
    This pass is used by URP's 2D renderer. I've never tried it but you can refer to the Lit shader to add one if you'd like to support 2D renderer as well.

    There are other passes in URP (check Complex Lit shader) that may be useful to you.

    UniversalForwardOnly:
    It's the same as UniversalForward, but UniversalForwardOnly forces Forward rendering.

    In other words, if an (opaque) object's shader doesn't have a UniversalGBuffer pass in Deferred path, it will be invisible because UniversalForward pass is not executed.
    DepthNormalsOnly:
    It's the same as DepthNormals, but it forces Forward rendering.

    I remember that DepthNormals pass won't be executed in Deferred path. I may be wrong here, but if there's UniversalForwardOnly, it's better to change DepthNormals to DepthNormalsOnly.​
     
    Last edited: Apr 20, 2023
  3. GiorgioK

    GiorgioK

    Joined:
    Oct 20, 2021
    Posts:
    34
    Thanks for the answer. I thought no one would answer.

    I figured out a bit with the UniversalGBuffer pass and studied what "deferred rendering" is in the URP.
    After enabling deferred rendering, the bushes in my scene started to render more realistically. The experiment also showed that if deferred rendering is enabled and there is no UniversalGBuffer pass in the shader, then the 3D object is not rendered at all - it is not visible.

    DepthOnly and DepthNormals passes.
    If I understood correctly, then to see the difference between the shader in which these passes are present and the one in which these passes are not, you need to execute:
    1) in URP Asset enable depth texture
    2) 'Use Pipeline Settings' or 'On' is selected for 'Depth Texture' in the main camera.
    3) the shader must use _CameraDepthTexture and/or _CameraNormalsTexture, etc. in its code.
    I'm right?

    Meta pass.
    As I wrote earlier - I did not notice any difference with this passage and without it.
    I set the Static parameter to "Contribute GI", will delete this pass - I did not notice any difference when baking the light, the speed is the same.

    Pass Universal2D.
    This pass includes the file com.unity.render-pipelines.universal\Shaders\Utils\Universal2D.hlsl
    I looked at his code. Here is the fragment shader program for this pass:
    Code (CSharp):
    1. half4 frag( Varyings input ) : SV_Target {
    2.    half2uv = input.uv;
    3.    half4 texColor = SAMPLE_TEXTURE2D( _BaseMap, sampler_BaseMap, uv );
    4.    half3 color = texColor.rgb * _BaseColor.rgb;
    5.    half alpha = texColor.a * _BaseColor.a;
    6.    AlphaDiscard( alpha, _Cutoff );
    7.  
    8.    #ifdef _ALPHAPREMULTIPLY_ON
    9.        color *=alpha;
    10.    #endif
    11.    return half4(color, alpha);
    12. }
    She is very simple. Here, even the normal map is not used - only BaseMap and alpha channel.
    Most likely this pass is used by Unity and/or URP for some technical purposes and it is not used in real rendering of 2D games and 2D objects.
     
  4. wwWwwwW1

    wwWwwwW1

    Joined:
    Oct 31, 2021
    Posts:
    769
    I'd say partially correct.

    There're two ways to render depth to "_CameraDepthTexture":
    1. Copy the camera's depth results after rendering opaque objects if not using OpenGL ES.
    2. Use DepthPrepass to render depth before rendering opaque objects.​

    When using the copy depth method, the "_CameraDepthTexture" will not be available during or before opaque objects rendering.

    If URP find that there's no need to render Depth Prepass (e.g., no SSAO, or SSAO with after opaque), it will copy depth after opaque (or again after transparent) rendering.

    As you can see, there's a "Force Prepass" option in newer URP version to manually force prepass rendering.
    URP_DepthTextureMode.png

    If any renderer feature (or post-processing effect) requires scene normals with
    ScriptableRenderPassInput.Normal
    , URP will enqueue a DepthNormalsPrepass.
     
  5. wwWwwwW1

    wwWwwwW1

    Joined:
    Oct 31, 2021
    Posts:
    769
    By the way, URP doesn't (or can't) detect operations in your shader. All of these are done in URP's C# rendering code.
     
  6. wwWwwwW1

    wwWwwwW1

    Joined:
    Oct 31, 2021
    Posts:
    769
    If objects are set to Contribute GI static and lightmap settings are correct, Unity should throw a red warning that the object's shader doesn't have a meta pass. The baking will continue but the object will be ignored by Enlighten or PLM as if it doesn't exist during lightmap calculations.
     
  7. GiorgioK

    GiorgioK

    Joined:
    Oct 20, 2021
    Posts:
    34
    It seems that I figured out the DepthOnly and DepthNormals passes.
    I haven't fully figured out the Meta pass yet. But I don’t need it yet, I wanted to study it all for the future. For now, that's enough for me. There may be questions later.
     
    DevDunk and wwWwwwW1 like this.