Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Have a look at our Games Focus blog post series which will show what Unity is doing for all game developers – now, next year, and in the future.
    Dismiss Notice

Question The fragment of ShadowCaster in URP

Discussion in 'Universal Render Pipeline' started by llxwd008, Sep 25, 2022.

  1. llxwd008

    llxwd008

    Joined:
    Aug 7, 2015
    Posts:
    49
    Hi,
    I'm learning URP code for Shadow, but have some doubts. We cast shadow use shader pass "LightMode" = "ShadowCaster" in file Lit.shader, It use ShadowPassVertex for vertex and ShadowPassFragment for fragment, which are defined in ShadowCasterPass.hlsl
    I can understand the function ShadowPassVertex. But I am confused about ShadowPassFragment, it nearly does nothing. But I can find correct shadowmap texture in FrameDebugger. In my opinion, to get shadowmap, I should write depth in light space for shading point. But this ShadowPassFragment in URP write nothing, why? which is the real fragment?
     
  2. lilacsky824

    lilacsky824

    Joined:
    May 19, 2018
    Posts:
    134
    You don't need write depth value in fragment shader manually.

    If you don't use semantic like SV_Depth in fragment shader to write depth ,
    it will use clip space position(SV_POSITION) to calculate depth value when rasterization stage.

    You can check this page for some information. (See chapter Vertex shader outputs and fragment shader inputs)
    https://docs.unity3d.com/Manual/SL-ShaderSemantics.html
     
  3. burningmime

    burningmime

    Joined:
    Jan 25, 2014
    Posts:
    605
    Depth buffer was a thing from before programmable shaders when GPUs just drew stuff on the screen instead of mined bitcoin and only had a few fixed functions. Back then, you had no shaders at all, you just gave a few fixed commands and the GPU had to figure out how to draw it. Think 1990s arcade games, PlayStation1, or N64. So you just had one bit to switch - ZWrite On or ZWrite Off. That stayed true after shaders were added since it's a useful optimization.

    As @lilacsky824 says, you can control it with
    SV_Depth
    , but that turns off early Z and is much slower. Avoid using
    SV_Depth
    unless you really, really have to. Just output the vertex position from vertex shader using
    SV_Position
    and the GPU will do its magic.

    By the way if you *don't* want to write out depth, set ZWrite Off. Do this for transparent geometry. But obviously not useful in shadows (except in HDRP 'cause they're not using depth-based shadow maps).
     
  4. llxwd008

    llxwd008

    Joined:
    Aug 7, 2015
    Posts:
    49
    Thanks, I have read the doc.
    'A vertex shader needs to output the final clip space position of a vertex, so that the GPU knows where on the screen to rasterize it, and at what depth.'
    So , after vertex, GPU will get the depth info, so I don't need to write it by myself. It seems that, In FrameDebugger, it use the depth info in the shadow map, as my follow screenshot URP_Shadow.png
    It shows that to render the left shadowmap texture, it use Pass ShadowCaster. I mean, in the code of the this Pass, I can't find any code related to depth. We get the depth after ShadowPassVertex, but did'nt use it in ShadowPassFragment. So how does the left shadowmap texture come out? Is there any default rules?
     
  5. funkyCoty

    funkyCoty

    Joined:
    May 22, 2018
    Posts:
    594
    When you or URP setup to draw to the screen, textures must be bound for writing. In URP's case, it will bind a depth and a color texture. Your fragment shader will write the returned value to the color texture. But the vertex shader, by default, will end up writing the depth value to the depth texture. You can override this behavior, but you do not need to usually, as you could just modify your vertex shader to change the depth value.
     
  6. llxwd008

    llxwd008

    Joined:
    Aug 7, 2015
    Posts:
    49
    Thanks you.
    So, the left pic in my screenshot, the shadowmap doesn't show the color texture, it really show the depth texture, it has nothing relation with ShadowPassFragment(this is for color output). In other case of FrameDebugger Pass, left picture shows color texture in most case. Is that so?
     
  7. funkyCoty

    funkyCoty

    Joined:
    May 22, 2018
    Posts:
    594
    Almost. It's not entirely accurate to say that the fragment shader has nothing to do with the depth buffer, even by default. If you follow URP's ShadowCaster pass's macro layer junk, you will eventually find something like "if alpha < 0.5, clip()" - for cutout shaders, so they don't write to the depth buffer either. If the fragment is not clipped, depth will be written (derived from the vertex pass, as others have stated before).
     
  8. llxwd008

    llxwd008

    Joined:
    Aug 7, 2015
    Posts:
    49
    Thank you very much, I want to know more info, in URP code, MainLightShadowCasterPass.cs, in function Configure, we call GetTemporary to get the shadowmap texture in GPU, so this texture id , include both color buffer and depth buffer, in MainLightShadowCasterPass, we get this shadow texture, has both color and depth info for later use, is that so?