Shadow cascades weird since 7.2.0

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?

5476695--560439--Screen Shot 2020-02-13 at 9.04.24 pm.jpg

2 Likes

Hey,
That's very weird!

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

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.

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.

3 Likes

You're 100% correct. I will do better for the next releases.

1 Like

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!

I have similar issues but I am not sure what to upgrade. It must be something to do with my shader, but I am not sure where to look at

Edit: this seems a good start: https://docs.unity3d.com/Packages/com.unity.render-pipelines.universal@7.2/manual/upgrade-lwrp-to-urp.html but didn't work

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.

1 Like

Cheers! This worked for me as well.

1 Like

@sebas771 Hmm. Actually it removes the glitch but i've just noticed it's removed my terrain shadows as well!


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

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.

3 Likes

it's very strange it worked for me with no problems, I have no clue tho

So the correct answer to this is that you have to compute the shadow coords in the fragment shader now:

#if defined(MAIN_LIGHT_CALCULATE_SHADOWS)
   IN.shadowCoord = TransformWorldToShadowCoord(WorldSpacePosition);
#else
   IN.shadowCoord = float4(0, 0, 0, 0);
#endif

There may be more to it than this though- but with Unity's policy of never documenting shaders it's hard to know.

1 Like

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

So I’m guessing they use the interpolator for light mapping and pixel computed for cascades.

1 Like

I'm sorry for the lack of docs in the changes. We will do better in the next releases.

@jbooth_1 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:

#if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)
    float4 shadowCoord : TEXCOORD7;
#endif

#if defined(REQUIRES_WORLD_SPACE_POS_INTERPOLATOR)
    float3 positionWS : TEXCOORD2;
#endif

In vertex shaders:

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

#if defined(REQUIRES_WORLD_SPACE_POS_INTERPOLATOR)
    output.positionWS = vertexInput.positionWS;
#endif

Then in the fragment shader we either use the shadow coordinates from the vertex shader or calculate them if we have shadows:

#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

#if defined(REQUIRES_WORLD_SPACE_POS_INTERPOLATOR)
    inputData.positionWS = input.positionWS;
#endif
5 Likes

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.

3 Likes

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.

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.