Why is my ivy not casting static shadows?

I have these beautiful static mesh ivies from Megascans, but I can’t get them to cast static meshes on the wall. They only cast dynamic shadows with two cascades, but that’s too heavy on 4k.

Dynamic shadows with two cascades, this is what it should look like:

Only one cascade, no static shadow:

There should be more than enough lightmap texels:

Settings:

Ideas? I’ve tried doubling the lightmap res on the wall, I’ve tried enabling “cast shadows as masked” on the ivy material, all to no avail.

As long as you are inside the specified unit range for Cascaded shadowmaps you will NEVER get any static direct shadows visible…they fade in after the cascaded shadowmap. The only thing you will see inside the range of CSM is indirect shadowing since thats basically just GI. So if you want to have shadows from the Ivy you have a couple of options:

  • Do what you do now, but have more cascades (this is really not a problem…I usually run 5000 units distance and 3 cascades)
  • Dont use CSM and bake sun shadows too…then you will get what you want cause everything is just static, you will have moving shadows from leafs anymore though
  • You could enable screenspace contact shadows to compensate for lack of resolution of the CSM

Those are basically your options :slight_smile:

Cheers!

Thanks for the info Daedalus! Love your lighting academy, everything I know about lighting in Unreal I learned from you.

That’s a bit of a downer, I need dynamic shadows because there’s moving parts. The range is already just 3000 units, but because the application needs to run on 4k (in some cases on a 1060), having two cascades kills the performance (the shadows are right on top of the profiler).

I’ll see how contact shadows perform - they look great in any case, never used those before.

Haha…thanks man, glad you enjoy the videos! :slight_smile:

Ah, I understand your limitation better now, thanks! What you could also try is go for 2 cascades and lower the overall shadowmap resolution to 1k…I think the default is 2k. But fool around with those settings via console (something like r.shadowmapblabla or cascadedshadowmapblabla^^ should get you there :D) you migth want to try out changing filtering options too to get some sharper shadows if you lower the rez. I guess in your scenario its just really carefully tweaking all the components to make it work. The console tweaks can be added to the .ini so you have them always when you run the editor or game.

Cheers!

While the contact shadows look nice on the ivy,

they create plenty of unwanted shadow artefacts on the rest of the scene, so I’d rather steer clear.

Changing r.shadow.maxresolution strangely has no visual effect at all, no matter what value I change it to (it started at its 2048 default). Min res was deafult at 32, so it can’t be overridden by that. Am I missing something?

r.ShadowMaxResolution is for point and spot lights. r.shadow.MaxCSMResolution is for your Cascaded Shadow Map.

What part of the dynamic shadow is expensive? Shadow Depths or Projection?

Lowering the resolution, number of cascades, and number of objects casting a dynamic shadow will improve the depth cost. If you have programming support, lowering the number of tris in the meshes casting a dynamic shadow(through a proxy mesh or LOD version) will definitely help as well.

Have you adjusted the shadow bias settings at all? Bias is dependent on resolution, but it’s possible to get some small-scale detail back with minimal shadow banding.

Not sure how 4k and a 1060 are going to play nicely at all, shadows or not. The good news there is 4.19 has temporal upscaling, meaning you’ll be able to effectively run at “4k” at up to half the actual res. This sounds like a much better optimization avenue, notes are here: https://forums.unrealengine.com/unre…e-4-19-preview

Good tips, I’ll check it out when I’m back in the office.

That’s good to know! And the 1060 - 4k combo was a bit of an unfortunate turn of events, I had to turn down the screen percentage to 80 or 70%.

So, this is how we ended up solving the issue: