Search Unity

Shadow cascades weird since 7.2.0

Discussion in 'Universal Render Pipeline' started by transat, Feb 14, 2020.

  1. transat

    transat

    Joined:
    May 5, 2018
    Posts:
    779
    I've been getting a border at the edge of my shadow cascades since I updated to 7.2.0 (and now 7.2.1). Any ideas what could be causing this?

    Screen Shot 2020-02-13 at 9.04.24 pm.png
     
    Shiiv and Rowlan like this.
  2. Elvar_Orn

    Elvar_Orn

    Unity Technologies

    Joined:
    Dec 9, 2019
    Posts:
    162
    Hey,
    That's very weird!

    Can you strip the project down and file a bug report so I can take a look at it?
     
  3. vetasoft

    vetasoft

    Joined:
    Nov 15, 2013
    Posts:
    432
    Same issue, I can't find the solution.

    Work great with universal lit, but costume shader like Toony Colors Pro 2 (generate with 2.0) since 7.2.0 ( and 7.2.1) have strange glitch when shadow cascades is set to two or four.

    It's work with no cascades.
     
  4. transat

    transat

    Joined:
    May 5, 2018
    Posts:
    779
    My project is too big to send but my issue is probably because I’m using a custom terrain shader (as 99% of users probably are). According to asset store developers, there have been changes to shadowing in 7.2.0. and these have broken custom shaders.

    I’m sure the developers will fix this at their end. What you could do at your end though, is communicate better with the said developers so they don’t get surprised by such changes. They shouldn’t have to find out via one star “it’s not working” user reviews.
     
    funkyCoty, Elvar_Orn and jbooth like this.
  5. Elvar_Orn

    Elvar_Orn

    Unity Technologies

    Joined:
    Dec 9, 2019
    Posts:
    162
    You're 100% correct. I will do better for the next releases.
     
    Last edited: Feb 19, 2020
    transat likes this.
  6. sebsmax

    sebsmax

    Joined:
    Sep 8, 2015
    Posts:
    118
    this is not an issue of URP 7.2.0, but of the terrain shader that is still using 7.1.8 shader.

    the light and shadow behavior are embeded inside the shader, so if you update to 7.2.0 without upgrading the terrain shader, this is what you get!
     
  7. sebas77

    sebas77

    Joined:
    Nov 4, 2011
    Posts:
    1,642
    Last edited: Feb 20, 2020
  8. sebas77

    sebas77

    Joined:
    Nov 4, 2011
    Posts:
    1,642
    If you have a custom shader, this is very likely due to the shadowcoord computation.

    it should be computed like this:

    #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)
    output.shadowCoord = GetShadowCoord(vertexInput);
    #endif

    the new define is important, because apparently is not always true.
     
    transat likes this.
  9. transat

    transat

    Joined:
    May 5, 2018
    Posts:
    779
    Cheers! This worked for me as well.
     
    sebas77 likes this.
  10. transat

    transat

    Joined:
    May 5, 2018
    Posts:
    779
    @sebas77 Hmm. Actually it removes the glitch but i've just noticed it's removed my terrain shadows as well!
     
  11. sebas77

    sebas77

    Joined:
    Nov 4, 2011
    Posts:
    1,642
    Ouch that's all I had to do to make it work, but be sure it compiles if the define is true you may not have a vertex input defined and in that case you may need something else
     
  12. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    5,461
    Unity does such an amazingly crappy job of communicating or documenting changes to the shader. I spend all my time diffing stuff on GitHub after every release trying to figure out what they have broken or added. It makes SRP support a nightmare, and now consumes about 100% of my development time such that I have no time left to actually work on my project. Removing surface shaders and not replacing it with a similar abstraction layer is the stupidest thing Unity has ever done- it's made their engine the hardest engine to support shaders in when it was previously the easiest.

    Also, the fix listed here doesn't work at all. Currently searching through change lists as none of this stuff is documented, as usual, thanks Unity.
     
    DannyBoyOnline, funkyCoty and Rowlan like this.
  13. sebas77

    sebas77

    Joined:
    Nov 4, 2011
    Posts:
    1,642
    it's very strange it worked for me with no problems, I have no clue tho
     
  14. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    5,461
    So the correct answer to this is that you have to compute the shadow coords in the fragment shader now:

    Code (CSharp):
    1. #if defined(MAIN_LIGHT_CALCULATE_SHADOWS)
    2.    IN.shadowCoord = TransformWorldToShadowCoord(WorldSpacePosition);
    3. #else
    4.    IN.shadowCoord = float4(0, 0, 0, 0);
    5. #endif
    There may be more to it than this though- but with Unity's policy of never documenting shaders it's hard to know.
     
    Rowlan likes this.
  15. sebas77

    sebas77

    Joined:
    Nov 4, 2011
    Posts:
    1,642
    the actual c ode I use in the VS is this:

    #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)
    o.shadowCoord = TransformWorldToShadowCoord(lwWorldPos);
    #endif

    and as far as I got in my case REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR is actually false, so it's not even computed.

    When I asked if it's ok if it's not computed, I have been told:

    "But yes, the problem is that we removed screen space shadows so the shadow coords have to be computed a little bit differently and we also have better defines that needed to be changed."

    but I did't investigate further because I have no knowledge of shadowing algorithms so I wouldn't understand anyway.

    Edit: Oh Sorry you are right, I haven't noticed that in the fragment this code changed too:

    #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)
    inputData.shadowCoord = input.shadowCoord;
    #elif defined(MAIN_LIGHT_CALCULATE_SHADOWS)
    inputData.shadowCoord = TransformWorldToShadowCoord(inputData.positionWS);
    #else
    inputData.shadowCoord = float4(0, 0, 0, 0);
    #endif

    This should the correct fix, as written by @Elvar_Orn
     
  16. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    5,461

    So I'm guessing they use the interpolator for light mapping and pixel computed for cascades.
     
    sebas77 likes this.
  17. Elvar_Orn

    Elvar_Orn

    Unity Technologies

    Joined:
    Dec 9, 2019
    Posts:
    162
    I'm sorry for the lack of docs in the changes. We will do better in the next releases.

    @jbooth The PR you're looking for is this (if it's for the cascade shadows)
    https://github.com/Unity-Technologies/ScriptableRenderPipeline/pull/4979

    We now have four extra defines that are used in our code.

    MAIN_LIGHT_CALCULATE_SHADOWS
    Defined when shadows on main light are enabled and shadows enabled in the material

    ADDITIONAL_LIGHT_CALCULATE_SHADOWS

    Defined when shadows on additional lights are enabled and shadows enabled in the material

    REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR

    Defined when shadows on main light are enabled, shadows enabled in the material and cascades set to none. Used to determine whether shadow coordinates need to be passed from the vertex shader to fragment shader.

    REQUIRES_WORLD_SPACE_POS_INTERPOLATOR
    Defined when shadows there are additional lights or shadow cascades set to two or four. Used to determine whether the world space position needs to be passed from the vertex shader to fragment shader.​

    These defines then get used in the following places.

    In Varyings struct that gets passed from the vertex shader to fragment shader:
    Code (csharp):
    1. #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)
    2.     float4 shadowCoord : TEXCOORD7;
    3. #endif
    4.  
    5. #if defined(REQUIRES_WORLD_SPACE_POS_INTERPOLATOR)
    6.     float3 positionWS : TEXCOORD2;
    7. #endif
    8.  
    In vertex shaders:
    Code (CSharp):
    1. #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)
    2.     output.shadowCoord = GetShadowCoord(vertexInput);
    3. #endif
    4.  
    5. #if defined(REQUIRES_WORLD_SPACE_POS_INTERPOLATOR)
    6.     output.positionWS = vertexInput.positionWS;
    7. #endif
    8.  
    9.  
    Then in the fragment shader we either use the shadow coordinates from the vertex shader or calculate them if we have shadows:
    Code (CSharp):
    1. #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)
    2.     inputData.shadowCoord = input.shadowCoord;
    3. #elif defined(MAIN_LIGHT_CALCULATE_SHADOWS)
    4.     inputData.shadowCoord = TransformWorldToShadowCoord(inputData.positionWS);
    5. #else
    6.     inputData.shadowCoord = float4(0, 0, 0, 0);
    7. #endif
    8.  
    9. #if defined(REQUIRES_WORLD_SPACE_POS_INTERPOLATOR)
    10.     inputData.positionWS = input.positionWS;
    11. #endif
    12.  
     
    Last edited: Feb 25, 2020
    jason_yak, Rowlan, transat and 2 others like this.
  18. bfoddy

    bfoddy

    Joined:
    Mar 27, 2012
    Posts:
    85
    This also broke my shadows. I guess I'll have to write to all the asset authors who wrote the shaders I'm using, and ask them to upgrade.

    As this is now Unity's recommended default rendering pipeline for new projects, and since pacman always pulls the latest version of it, you should probably try to limit breaking changes as much as possible from here forward - documented or not. Changing an API between minor bugfix releases is for alpha software.
     
  19. chalogr

    chalogr

    Joined:
    Aug 24, 2016
    Posts:
    5
    I'm also getting this in URP 7.3.1. Any guidance for people who have never patched Unity? Where can I start? I really want to fix this issue.
     
  20. sebsmax

    sebsmax

    Joined:
    Sep 8, 2015
    Posts:
    118
    I'm pretty sur @Elvar_Orn just explained how to patch it two post above yours.

    You can also do a diffcheck on Git to see what has been changed between your version and the new version.
     
  21. JMittigMimic

    JMittigMimic

    Joined:
    Sep 25, 2019
    Posts:
    1
    Why do you have two input-structures in the fragment shader? "inputData" and "input"
    I guess "input" is the Varyings structure, but what is inputData then. I would appreciate if you could calrify.
     
  22. Elvar_Orn

    Elvar_Orn

    Unity Technologies

    Joined:
    Dec 9, 2019
    Posts:
    162
    You're correct, input is the Varyings struct sent from the Vertex to the Fragment shader.

    InputData another struct that we initalize in the fragment shader using the Varyings data sent in and pass on to our lighting functions like UniversalFragmentPBR() and UniversalFragmentBlinnPhong()...



    half4 LitPassFragment(Varyings input) : SV_Target
    {
    UNITY_SETUP_INSTANCE_ID(input);
    UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);

    SurfaceData surfaceData;
    InitializeStandardLitSurfaceData(input.uv, surfaceData);

    InputData inputData;
    InitializeInputData(input, surfaceData.normalTS, inputData);

    half4 color = UniversalFragmentPBR(inputData,...);
    ...
    }
     
  23. bfoddy

    bfoddy

    Joined:
    Mar 27, 2012
    Posts:
    85
    Pretty hilarious how when Unity went from 2019.3.7 to 2019.3.8 it took away the option of installing SRP below 7.3.1, even though 7.3.1 is full of breaking changes. Don't envy anyone whose job is to write shaders right now.
     
    Two_Fifty likes this.
  24. Dawdlebird

    Dawdlebird

    Joined:
    Apr 22, 2013
    Posts:
    88
    Hm, well at least there is some info on it here... Also just found my lighting broken since I've upgraded my project the other day (this shadow thing just being a few of them... I have a post processing pass relying on alpha that now renders my scene either black or as completely transparent).

    - I don't get it though; it was working fine, so why this change? We now need extra calculations in our fragment shaders for the same effect, but isn't that a step backwards? Or did you previously handle this in the GetMainLight function that takes these shadow coordinates, and stripped it from there?
     
    Last edited: May 4, 2020
    nasos_333 and AA-Matt like this.
  25. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    5,461
    So I'm still having issues from this change - a new one reported. For some reason, the shadows just don't line up with what the Unity terrain shadows show:

    Here's MicroSplat, with the changes above:



    and here's the unity shader:



    This is with 4 cascades.

    In the pixel shader I do:

    Code (CSharp):
    1. #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)
    2.     inputData.shadowCoord = input.shadowCoord;
    3. #elif defined(MAIN_LIGHT_CALCULATE_SHADOWS)
    4.     inputData.shadowCoord = TransformWorldToShadowCoord(inputData.positionWS);
    5. #else
    6.     inputData.shadowCoord = float4(0, 0, 0, 0);
    7. #endif
    8.  
    9.  
    10.                 half4 color = UniversalFragmentPBR(
    If I understand correctly, the vertex shader shouldn't matter here because we'll be taking the second pathway. And yes, inputData.positionWS is the world space position of the pixel.
     
  26. nasos_333

    nasos_333

    Joined:
    Feb 13, 2013
    Posts:
    13,348
    I have a _MAIN_LIGHT_SHADOWS in my defines, has this changed ?

    This all is EXTREMELY confusing, i just cant get my shadows right in a custom shader, is near impossible to spend months to do a simple thing like that because URP is changing 1000% every second and nothing is obvious or documented.

    Please consider to remove the pipelines from users production lines as nothing works between versions, is strange to send for production a pipeline that is not even in pre-pre-pre-beta stage.

    Also there is zero consideration of users that stated projects in other than latest Unity, right now is impossible to know what Unity and URP to use, and noone knows if anything will be working in just next version of Unity or URP, it is an impossible situation.

    The pipelines scheme is just extremely confusing and hard to keep up with and should be labeled as extremely experimental and as an extreme risk to use in a project by Unity, to showcase their exact nature and prevent users from putting their hard work to such a huge risk.

    Also is now obvious why point light shadows take forever to create, the URP is just extremely complex and not user friendly for any advanced production and shader programming. On top of that it changes every minute completly, so even if spend months and make something in one version, the next day maybe broken and have to start all over with totally new things and handling. It is just nowhere near ready to use in production besides the simplest of projects perhaps.
     
    Last edited: Oct 16, 2020