Very interesting solution! I can see this becoming an official workflow. Epic need to allow meshes to have Nanite set per material slot rather than the whole mesh. this would be the best solution in my view. Then you could have both states in one static mesh. Would also help for situations where you have translucent materials for windows/glass/liquid without forcing the entire mesh to be non-nanite. There is an issue with the solution in this video - If the WPO on the Nanite mesh is too extreme (such as strong winds making the trunk bend), the shadow would not match. Same goes for any kind of gathering situation, where you want to cut the tree down. I suppose in that case you'd have to completely disable one mesh from rendering while letting the other render and cast shadows, and accept the non-cached shadows for the duration of the event.
Yeah, my guess is that in the future Epic will have a checkbox to disable WPO on shadows in Nanite Trees. For now, this works. We are purposefully rendering shadows that don't move with the tree here, so that is the trade-off we are making. For some, that won't be a compromise they can make, but for what we are using this for, having shadows that don't match the tree is okay.
@@SabreDartStudios What happens if you use the Shadow Switch as input for WPO? Does that still invalidate the cache if there is no input for the shadow pass? Edit: Forgot WPO is done before the shadow pass, so it has no effect sadly.
An other possible solution would be to have a setting in the material itself. Something like a "ignore WPO for shadow rendering" checkbox that would let the engine create extra shader variants without the WPO. The mesh would be rendered with WPO during its render pass pass the shadow pass would just use the shader with the WPO disabled.
@@SabreDartStudios You could go one step further and setup an LOD, where once you get really close to a tree then it does enable WPO shadows. This only makes sense as you wouldn't be able to see the difference between regular and WPO shadows from a distance anyways but once you get really close you don't have to compromise.
I am sure they are aware and there will be a better way to handle this in the future. Nanite foliage is still an experimental feature and we don't even have a full release of 5.1 yet.
@@SabreDartStudios I guess, UE is kind of all over the place so you never know what's actually gonna get finished and what's just left for us users to hack through
@@SabreDartStudios Im a bit confused about calling this a Nanite foliage issue, its a virtual shadow map issue, cache invalidation happens with WPO, regardless of nanite, it does not care about it, or Am i missing something?.
@Guillermo Otero That is correct, it isn't a Nanite Foliage issue, it is just that 5.1 added support for WPO in Nanite Foliage and so that is what we are testing. It is entirely a VSM issue, but it does impact Nanite Foliage when WPO is enabled.
Brilliant! This needs to be implemented in UE !!! Would be perfect, when in the end we would simply get a checkbox in the foligae settings saying "static virtual shadows"
This really needs to be added to the engine. Thanks for revealing why the frame rates cratered with only a few trees. I was scratching my head trying to figure out why this was happening when nanite was supposed to handle bazillions of polys.
There should be a way to tell it to only update the VSM e.g. every X frames so that it still updates, but at a lower framerate to reduce the performance hit. It can be an even smarter scheduler to update more when there are less objects to update, and less when there's more. Also which objects to update could be done pseudo randomly so that there are no distinct periodic patterns, making it look better when there are a ton of objects.
I consulted with other people and they said there is no need for this workaround or plugin as the official release of 5.1 has a single command that fixes this. Assume r.Shadow.Virtual.DistantLightMode is that cmd, but correct me if I'm wrong about this.
Yeah, I saw r.Shadow.Virtual.DistantLightMode in the UE 5.1 release notes. Unfortunately it doesn't attempt to solve the same problem this video and plugin solve. r.Shadow.Virtual.DistantLightMode is about decreasing the frequency of VSM cache updates in the distance (which has its own use case). This video and plugin are trying to solve the issue of WPO VSM cache invalidations when you are right up under trees in a dense forest and shadows cover a large portion of the screen. I just tested r.Shadow.Virtual.DistantLightMode 1 on the test project I show in this video (without the shadow proxies) and there is no noticeable performance increase. I then use the shadow proxies method and the fps goes from 12 fps to 35 fps at full-screen 4k (66% screen percentage) with a dozen tree shadows covering 3/4 of the screen. I also noticed the UE 5.1 release notes seem to be endorsing the method in this video: "Nanite-enabled meshes now support the Hidden Shadow flag. This allows custom shadow proxy meshes to be Nanite, improving the performance of Virtual Shadow Maps."
@@SabreDartStudios SO let me ask you something. If I'm NOT concerned with performance because say, I'm a filmmaker with an RTX 3090 only worried about reaching 24 fps max (not distributing games) and perhaps my "quality of life in the editor", is there any rendering or visual issues that are affected?
If you are not concerned about performance because you are a filmmaker, then you probably do NOT want to follow the method/plugin in this video which is for video games. If you follow this method, then your shadows will stop moving and will not match the movement of the leaves. I am not a filmmaker, but I would assume this loss of quality would be an issue. As I mention in the video, the tradeoff we make here of losing our moving shadows isn't something that everyone will be able to accept, but for the special kind of video games we make, the tradeoff was acceptable.
@@SabreDartStudios Here's two more commands from the MAWI folks that may be worth testing:r.Shadow.Virtual.Cache.MaxMaterialPositionInvalidationRange 0 r.Shadow.Virtual.Cache.DebugSkipDynamicPageInvalidation 1
I've got thousands of nanite trees on a landscape 500x500, and my entire screen is blue in that cached shadow thing. My FPS jumps around from 30-90 depending on where I am. My setting is quite dark though so I'm not sure the trees even need shadows to begin with.
In the long run Epic will probably add some other option to fix this issue, so this won't end up being that useful. I just kind of wanted to tell the story of how we solve problems :)
this is amazing! thank you for your work. i was curious about the exact ms gained with this method, were you able to do some performance test with this compared to regular nanite foliage?
It all depends on how many trees you have in an area. If you place enough trees in a small area you will end up at less than 1 fps. Then if you use this method that 1 fps goes to close to 50 fps on a GTX 2080 Super. So it is a pretty big (50 times) fps boost in the case of a high density of trees and shadows that cover most of the screen.
I could have done that. We are playing around with how to optimize the Foliage Shadow Imposters to see if we should use Nanite or non-Nanite and what LOD level we should use to get the best performance.
Amazing but, dude, at that distance you don't get to see the WOP. And, if in the end you are not using Nanite, why not use a different non wpo material for lods higher than 0? or for that matter you could use a material the would turn off WOP at a certain distance from the camera.
Our performance issues were with shadows when you get up close under the trees, not the shadows in the distance. Also, with Nanite Foliage, there isn't really the concept of LOD's, since Nanite self-LOD's. We are looking into other LOD solutions as well though. This was just a first step. Still a lot more to figure out before we have a complete Nanite Foliage workflow for our studio.
when I enable plugin in my project and restart cant open project becouse error "--------------------------- Missing Modules --------------------------- The following modules are missing or built with a different engine version: FoliageShadowImposters Engine modules cannot be compiled at runtime. Please build through your IDE. --------------------------- OK ---------------------------" any idea?
You need to install Visual Studio 2022 and set it up to work with Unreal Engine 5. If you need help doing this, you can contact me on Discord: discord.gg/WK9DhHpT
Hos are the impostors shadiwn the original tree? are there artefacts due to them occupying same space? ohw is it affecting the shadows on "moving" on the wind elements? I don't care for swinging of shadows on the ground but I would like the trees themselves to be properly light and rendered.
The Foliage Shadow Imposter is hidden, so it is not rendered and there are no artifacts. The original tree is properly lit and rendered. The main issue you would run into is that the shadow on the ground doesn't move with the movement of the tree, but that is the tradeoff we are willing to make here.
@@SabreDartStudios hey, that's what i figured immediately when you explained how it works in the video. I guess for very windy weather this isnt a solution, but I guess you always have to make trade offs! I suppose heavy wind is also very difficult to display in games, so that's why you usually dont see it in games. Thanks for the awesome explanation and the plugin!
how do I compile source code in VS, I didn't find any compile or build button maybe due to I opened the wrong file. Can you please tell me which file to compile and how? It would be a great help. Thank you
You can't compile the plugin directly. You have to put it in your UE project and then compile the UE project which will compile the plugin along with it: docs.unrealengine.com/4.26/en-US/ProductionPipelines/DevelopmentSetup/CompilingProjects/
That is correct. That is the tradeoff we are making to get the massive performance gains. The trees continue to move, but the shadows don't move with them.
There is a way to have Unreal automatically disable VSM cache invalidation on materials with WPO that are far from the camera. It says in the docs, "In some cases, creating Material LODs that remove WPO/PDO may be impractical, but the end effect of these transformations is small in the distance. Use r.Shadow.Virtual.Cache.MaxMaterialPositionInvalidationRange to set a distance (in centimeters) beyond which cache invalidations from these materials are ignored." I did not see this mentioned in the video. Have you tried this?
Yeah, we tried that, but the problem wasn't the shadows in the distance that were killing performance it was the shadows up close. The size of the shadow as a percentage of the screen was the main correlation with performance. So the worst performance was when we were directly under a tree. Because of this we decided to make the trade-of of having moving trees, but static shadows. This may not work for everyone, but for our project it is a compromise we are willing to make for the massive performance gains.
What happens if you set the range to something ridiculously low? Would that not result in the same outcome as in the video? Or does it get clamped so that you cannot force the invalidation to be removed completely?
@@SabreDartStudios I am running into some VSM issues and likely will try your solution soon, but yea, I'll need to figure how to get the Data Layers sync'd up. I have trees across 3-4 Data Layers. Maybe I can figure out how to do it, or if you update the plugin let us know?
Hello and thank you for this video. Even if the World Position Offset Distance parameter works in UE.2, your plugin is still useful to gain a bit of performance on animated foliage in the foreground, isn't it? Thank you.
Yes, I originally thought that the new World Position Offset Distance made the plugin no longer required. However, after more extensive testing, for our use case the plugin gets us dozens more fps than using the new setting.
Is there not a command that allows you to set virtual shadow maps to exclude foliage? The idea is for foliage to use the traditional shadow system and static nanite objects use virtual shadow maps. I tested this with non-nanite foliage and nanite ground and rocks which worked. I am not sure if this can be done with nanite foliage yet. This will save you the need to add additional trees.
Hey folk, thank you for this great solution. for some reason when I click on add foliage imposters UE5 crash 😑. do you have any idea how I can fix it (I am on 5.1.1). thank you
Hmmm, I am not sure. The only thing I can think is that there probably isn't anything stopping it from crashing if the Data Table has inaccurate values. If you jump in Discord we can troubleshoot it: discord.gg/CqvP7cNd
It just depends on how dense the forest is as to how much the dynamic shadow cost is. With a medium density forest of trees like I show in this video it goes from single digit fps up to around 40 or 50 fps on a 2080 Super. The less dense the forest, the less gain. The more dense the forest, the greater the gain.
While I think this is an amazing solution, and think you did a great job with it, there's one thing that prevents me from using it. I think it only solves half the issue, at least in my case. I've noticed that any moving lights in a scene, such as a day and night cycle, will produce the same issue and cause absolutely massive hits to performance. So it seems like, as far as I can tell, the only thing to do is wait for epic to fix the issue.
Yes, moving lights are always an issue for dynamic lighting systems and Epic cannot fix this. There is an easy fix though. You have to move your lights less often. The way games with day/night cycles do this is by moving the lights in steps periodically. I have a whole video about this, but here is the basic idea. Figure out what your cycle is for day/night (the longer the better). Then figure out the maximum amount of time you can go between moving the light and recalculating the shadows without it looking like the sun in the sky is jumping. If you have a long enough day/night cycle, this can be once every few seconds rather than once every frame. You combine that solution with the solution in this video and it works great in games with day/night cycles like ours.
@@SabreDartStudios Yep, this is exactly what I've done as well. It still gives way more of a performance hit than shadow maps pre-nanite, due to exactly what you've explained in your video. Even setting the rate to every few seconds, you can watch the visualizer as the whole scene turns pure red as it recalculates all the cached shadows. You may be right that it is something epic can't or will never fix. I'll also check out your other video on the subject, thank you for your time and tips.
Can someone here clarify something for me please? If the mesh for the impostor shadow isn't being rendered, and should net you performance is if it weren't being rendered, how is the shadow being calculated since it has to draw the texture mask and the tree mesh for the shadow? So is it netting the same performance as if the impostor tree weren't there? Or is there still a performance hit, but obviously not as severe as not having cached shadows?
Even though it isn't rendering the Foliage Shadow Imposter mesh to the screen there is still a cost for the duplicate tree to be in memory and render to VSM. This cost is small compare to the huge cost of invalidating the VSM cache every frame though. This is not the ideal solution. Eventually I expect they will add a setting to either the static mesh or the material to not use WPO when calculating the VSM. But this is all still experimental.
I enjoyed the video :) By way of a question: if you employ the solution you've proposed, but you have a moving lightsource such as a day-night cycle animated directional light, does this stop being a solution? My assumption is if the trees moving the shadows is killing fps, then the light moving shadows will be the same?
That is correct. If you constantly move the light source (Sun), then it will invalidate the shadows constantly, but this is why games with day night cycles DON'T move the light source constantly. They do it in small chunks. So instead of moving it every tick, you would move the light source every 5 seconds or something like that. You have to adjust it based on your day length so it doesn't look like it jumps in the sky. By doing this it only has to recalculate the shadows once every 5 seconds and so you still get a huge performance gain from caching the shadows for the five seconds in between.
We thought about this initially, but then it would be an actor and I don't think actors work with the foliage tools which are for placing instanced static meshes. We need HLOD performance from the foliage tool implementation of instanced static meshes, so we went this route instead. Eventually Epic will add a static mesh or material switch to fix this issue and we won't need duplicate meshes at all. Until then, this is what we are using.
This kinda is a let down but thank you for going over 5.1 nanite. I have been waiting for this for so long but it looks like it's not ready for a finished product just yet.
Thanks for the plugin. Looks like they've addressed the issue somewhat with PCG in 5.2. You can set the WPO distance for all foliage created procedurally including grass. Explanation here, ruclips.net/video/9DY9Xe1KRW8/видео.html
@@SabreDartStudios Ah that's depressing, I would have run into this issue as well. Just fixed it on my grass by disabling wind, since it's short and photorealistic it's not a huge deal you don't really see short grass move much irl and it's a small trade off for pushing boundaries on rendered geometry count. Still breaking new ground, normal to expect some trade offs but on trees that's huge. Thanks for the plugin, fingers crossed it helps.
dynamic sky does make it more difficult, but it does not break this. When you setup your dynamic sky with moving directional light for the sun, it is important to only move the light once every few seconds. Depending on your day length in minutes/hours, you can calculate the longest you can go between light movement updates without seeing the sun jump in the sky between movements. If you look through my videos, I have a video showing how to do this. By only updating the light periodically, the shadows can still be cached between and the performance is still good.
It isn't a culling distance issue. Trees in the distance have small shadows and low shadow rendering cost. Trees up close that cover the screen in shadows of multiple overlapping trees have a higher cost when rendered every frame. If you use the VSM Cache visualizer you can see that the shadowed areas are blue instead of green. This is the problem. If there is too much blue on screen, the fps hit is high. With the technique used in this video we turn the blue shadows into green shadows and massively increase fps in certain situations. In other situations with low tree density and low shadow overlaps, the performance increase may be much less.
Heya I just got sent this by a co-worker, have you guys considered just using the Shadow Pass Switch in the Materials instead? You hook the WPO result into it and just tell the shadow pass to not use any WPO = 0.
Unfortunately the Shadow Pass Switch isn't fixing the performance issue in UE 5.1 P2. Hopefully it will in future updates of UE5. r.Shadow.Virtual.Cache.MaxMaterialPositionInvalidationRange is also not working in UE 5.1 P2 to fix this issue.
Nice trick, thanks, but its basically rendering both trees? Because i cant get the Shadow Imposter to be invisible in game with foliage tool, there is no "Hidden Shadow" or Actor Hidden In Game", so I end up having 2 trees in one. ( I did not try the plugin, because I need to know first if it hides the imposter despite foliage type? Thanks!
In the imposter (shadow proxy) we set CastShadow to true, bHiddenInGame to true, and bCastHiddenShadow to true. You can do a proof of concept by setting those manually just like I did in this video without using the plugin. If you need any help with it you can contact me on Discord: discord.gg/WK9DhHpT
Great work thank you for sharing :) . I tried on unreal engine 5.1 its doesn't work or its only work with UE5? Here the message I got when I open my project. The following modules are missing or built with a different engine version: FoliageShadowlmposters Would you like to rebuild them now?
Welp, thank you. Now i know why nanite and all the settings needed to use it kill my fps, everything on screen is blue using cached page visualization mode. The reason tho? No clue.
The high cost of moving shadows from foliage, isn't really something Epic can fix in Unreal Engine. Moving shadows are expensive and there is no way around it. What we are doing with this plugin is giving up moving shadows to get a 200 to 300% fps boost, while still having foliage that moves in the wind. Each game will have to decide how much fps they need and what compromises they want to make to get there. For our game, giving up moving shadows to get massive fps gains was an easy choice. For other games, that might not be something you can give up.
I don't have 5.1 yet, will be getting it tomorrow to test, but I read through the patch notes and they seem to be endorsing my method. Search the 5.1 patch notes for Shadow Proxy or Shadow Proxies.
@@SabreDartStudios "Nanite-enabled meshes now support the Hidden Shadow flag. This allows custom shadow proxy meshes to be Nanite, improving the performance of Virtual Shadow Maps" hmm but how use it?
You use it exactly like I show in this video, except you enable Nanite on the shadow proxy mesh. We gained around 10 fps doing this in a scene with a lot of trees.
I haven't used the procedural foliage spawner in a long time, so I am not sure. It depends on if the procedural foliage spawner uses the Foliage system or not. I don't know.
Not sure if Shadow Imposters is the best name, Imposters are already their own thing and often used with foliage. Shadow Proxies might work better, and is the term cryengine uses for a similar approach for shadow optimization.
That is a good point. I was thinking of it as imposter for the shadow caster, but Shadow Proxy probably makes more sense. Interesting that CryEngine does something similar. I expect that Epic will fix this issue with a material setting in a future version and we won't need to use anything like this in production. This video was more just about telling the story we often go through to find solutions. I don't think we will end up using this workflow.
In the 5.1 release notes Epic is calling them "Shadow Proxies", so you were correct about the name :) "Nanite-enabled meshes now support the Hidden Shadow flag. This allows custom shadow proxy meshes to be Nanite, improving the performance of Virtual Shadow Maps."
Good question. I was wondering about this, so I tried it out and it works great. The reason it works is that the plugin operates on Instanced Foliage Actors and it just so happens the procedural foliage volume uses the same thing.
What GPU are you guys using? Granted that if trees are very far and not in playable area then WPO should be removed. Is it me or your diagnostic is wrong here? blue doesnt mean not cached but Static cached, its then dynamic cached only that you lose - red would be not cached at all. As noted in the comments 5.1 as also improved VSM considerably now and allows for hidden shadow nanite mesh, alongside Distance Field Shadows for far distance you should never have to do a trick like this while using Nanite.
The solution in this video is NOT to solve the issue with distant trees. We use Distance Field Shadows to cover distant trees. This solution is specifically to solve performance issues in dense forest when you are up close and under the trees. You are correct, blue is dynamic cached, but it is still way too slow compared to green. In very dense forests we are getting over 1,000% fps increases using the method in this video when up close and under the trees. Now some projects will not be okay with shadows that don't move to match the trees moving, but for the kind of games we make, it is a fair compromise for the MASSIVE performance boost. In the 5.1 patch notes it seems like Epic is endorsing the method we use in this video. They say: "Nanite-enabled meshes now support the Hidden Shadow flag. This allows custom shadow proxy meshes to be Nanite, improving the performance of Virtual Shadow Maps." While I didn't show it in this video, we have now switched to enabling Nanite on the shadow proxies and we are getting an additional 5 to 10 fps in the example project shown in this video. Comments have shared many other ways to try to solve this, but I have tried them all in 5.1 and they don't seem to work. I will be doing an update video soon to show those methods and discuss the Nanite shadow proxies change for additional performance. I am testing this on my 2080 Super and my new 4080. The percentage based fps increase is the same on both GPU's.
@@SabreDartStudios start piss me of this engine, should be time save but nothing work right, no landscape material displacement , poor performance nanite shadows etc
I disagree. These are all experimental features, so it makes sense that all the use cases aren't completely working yet. These are also pretty advanced features that you probably won't find in any other engines.
I think so. I don't have 5.1 yet, will be getting it tomorrow to test with, but I read through the patch notes and they seem to be endorsing my method. Search the 5.1 patch notes for Shadow Proxy or Shadow Proxies.
How do i do that, because im just building a world and am very new to UE, and id rather have shadows that look like Vanilla WoW untill my project is closer to being a game
I can imagine a world in the near future where everyone will be able to make trees with INDIVIDUALLY modeled leaves. Did you know that the average adult oak tree has somewhere around 250,000 leaves? I tried modeling one and ended up with more than two million polygons on a single tree. So yeah, this will be nice, especially with the world-offset stuff in the material pipeline being compatible with Nanite now!
Wow! That is a lot of polys! Nanite is definitely increasing the number of polys we can use, but two million per tree might still be a bit much if you can get close to multiple trees at once. Our testing right now is with trees closer to the 50k per tree range.
Not really. This is a new experimental feature (Nanite WPO / two-sided), so it makes sense that all the tooling around something experimental isn't all there yet. As I said in the video, I am sure Epic will come up with a solution for this that is built in, we just don't have it yet.
nobody cares about doesn't match it's own shadow, mate, as long ast it's leaves and branches shadows people will be busy surviving from the enemy in the game
As of Unreal Engine 5.2, the World Position Offset Distance setting is working.
As of Unreal Engine 5.3, you can set "Shadow Cache Invalidation Behavior" to "Rigid" to get the same effect that I show in this video.
Dart, you're my fricken hero dude. The way you break down the new features coming out in unreal is awesome.
Thanks!
This is awesome, thanks for explaining the problem and sharing the solution! I’m making a very tree-heavy project so this will be a big help!
Very interesting solution! I can see this becoming an official workflow. Epic need to allow meshes to have Nanite set per material slot rather than the whole mesh. this would be the best solution in my view. Then you could have both states in one static mesh. Would also help for situations where you have translucent materials for windows/glass/liquid without forcing the entire mesh to be non-nanite.
There is an issue with the solution in this video - If the WPO on the Nanite mesh is too extreme (such as strong winds making the trunk bend), the shadow would not match. Same goes for any kind of gathering situation, where you want to cut the tree down. I suppose in that case you'd have to completely disable one mesh from rendering while letting the other render and cast shadows, and accept the non-cached shadows for the duration of the event.
Yeah, my guess is that in the future Epic will have a checkbox to disable WPO on shadows in Nanite Trees. For now, this works. We are purposefully rendering shadows that don't move with the tree here, so that is the trade-off we are making. For some, that won't be a compromise they can make, but for what we are using this for, having shadows that don't match the tree is okay.
@@SabreDartStudios What happens if you use the Shadow Switch as input for WPO? Does that still invalidate the cache if there is no input for the shadow pass?
Edit: Forgot WPO is done before the shadow pass, so it has no effect sadly.
An other possible solution would be to have a setting in the material itself.
Something like a "ignore WPO for shadow rendering" checkbox that would let the engine create extra shader variants without the WPO.
The mesh would be rendered with WPO during its render pass pass the shadow pass would just use the shader with the WPO disabled.
Yeah, that would be great. Hopefully they add something like that.
@@SabreDartStudios You could go one step further and setup an LOD, where once you get really close to a tree then it does enable WPO shadows. This only makes sense as you wouldn't be able to see the difference between regular and WPO shadows from a distance anyways but once you get really close you don't have to compromise.
It's the little moments like this that make dev so enjoyable
It definitely is!
Well done! A simple solution to a complex problem explained well.
Thanks!
Thanks for this!!!
Good on you for explaining, making and releasing this!!
I was getting crazy abaout this problem!! thank yuo very much!
Wow that is amazing, thanks for pushing devs forward! Would be cool to see this plugin on the marketplace.
The UE5 devs should really automate or at least streamline this, there's no way they're not aware of the bad WPO shadow performance.
I am sure they are aware and there will be a better way to handle this in the future. Nanite foliage is still an experimental feature and we don't even have a full release of 5.1 yet.
@@SabreDartStudios I guess, UE is kind of all over the place so you never know what's actually gonna get finished and what's just left for us users to hack through
@@SabreDartStudios Im a bit confused about calling this a Nanite foliage issue, its a virtual shadow map issue, cache invalidation happens with WPO, regardless of nanite, it does not care about it, or Am i missing something?.
@Guillermo Otero That is correct, it isn't a Nanite Foliage issue, it is just that 5.1 added support for WPO in Nanite Foliage and so that is what we are testing. It is entirely a VSM issue, but it does impact Nanite Foliage when WPO is enabled.
this isn't really a solution though, but a (pretty good) workaround. ideally, you'd have high speed shadows
Brilliant! This needs to be implemented in UE !!! Would be perfect, when in the end we would simply get a checkbox in the foligae settings saying "static virtual shadows"
My hope is that it ends up just being a checkbox as well.
This really needs to be added to the engine. Thanks for revealing why the frame rates cratered with only a few trees. I was scratching my head trying to figure out why this was happening when nanite was supposed to handle bazillions of polys.
Great work! and explained very well
neat work arround, hope EPIC will come up with a native solution to this soon
I am sure they will. It is too big of an issue to ignore.
subscribed. this is goated. thanks for sharing your tech!
I just switxhed to ray tracing shadows on the direct and sky lights, doubled the performance and lioks way better
Love your channel!
Thanks! Hope it is helpful!
So awesome. Great work!
amazing!! Great idea and great solution!
There should be a way to tell it to only update the VSM e.g. every X frames so that it still updates, but at a lower framerate to reduce the performance hit.
It can be an even smarter scheduler to update more when there are less objects to update, and less when there's more.
Also which objects to update could be done pseudo randomly so that there are no distinct periodic patterns, making it look better when there are a ton of objects.
That would be kewl, but it doesn't look like the full 5.1 release has anything like that. So this is the best we can do for now.
Congratulations, great job 👏👏👏
Thanks!
Rather than playing the game you could simply hit the G key to view the game mode. It should hide items that have hidden in game checked
Nice!
Superb useful information, thanks. Subscribed 👍
that is so cool! What ge gonna do today Brain? haha
I consulted with other people and they said there is no need for this workaround or plugin as the official release of 5.1 has a single command that fixes this. Assume r.Shadow.Virtual.DistantLightMode is that cmd, but correct me if I'm wrong about this.
Yeah, I saw r.Shadow.Virtual.DistantLightMode in the UE 5.1 release notes. Unfortunately it doesn't attempt to solve the same problem this video and plugin solve. r.Shadow.Virtual.DistantLightMode is about decreasing the frequency of VSM cache updates in the distance (which has its own use case). This video and plugin are trying to solve the issue of WPO VSM cache invalidations when you are right up under trees in a dense forest and shadows cover a large portion of the screen. I just tested r.Shadow.Virtual.DistantLightMode 1 on the test project I show in this video (without the shadow proxies) and there is no noticeable performance increase. I then use the shadow proxies method and the fps goes from 12 fps to 35 fps at full-screen 4k (66% screen percentage) with a dozen tree shadows covering 3/4 of the screen. I also noticed the UE 5.1 release notes seem to be endorsing the method in this video: "Nanite-enabled meshes now support the Hidden Shadow flag. This allows custom shadow proxy meshes to be Nanite, improving the performance of Virtual Shadow Maps."
@@SabreDartStudios SO let me ask you something. If I'm NOT concerned with performance because say, I'm a filmmaker with an RTX 3090 only worried about reaching 24 fps max (not distributing games) and perhaps my "quality of life in the editor", is there any rendering or visual issues that are affected?
If you are not concerned about performance because you are a filmmaker, then you probably do NOT want to follow the method/plugin in this video which is for video games. If you follow this method, then your shadows will stop moving and will not match the movement of the leaves. I am not a filmmaker, but I would assume this loss of quality would be an issue. As I mention in the video, the tradeoff we make here of losing our moving shadows isn't something that everyone will be able to accept, but for the special kind of video games we make, the tradeoff was acceptable.
@@SabreDartStudios Here's two more commands from the MAWI folks that may be worth testing:r.Shadow.Virtual.Cache.MaxMaterialPositionInvalidationRange 0
r.Shadow.Virtual.Cache.DebugSkipDynamicPageInvalidation 1
I've got thousands of nanite trees on a landscape 500x500, and my entire screen is blue in that cached shadow thing. My FPS jumps around from 30-90 depending on where I am. My setting is quite dark though so I'm not sure the trees even need shadows to begin with.
I don’t know if this is useful or not and I don’t care, just listening to you is a pleasure!
In the long run Epic will probably add some other option to fix this issue, so this won't end up being that useful. I just kind of wanted to tell the story of how we solve problems :)
amazing work thanks for sharing! :)
Awesome solution, is that working with megascan trees? I also have asked about it in discord server
this is amazing! thank you for your work. i was curious about the exact ms gained with this method, were you able to do some performance test with this compared to regular nanite foliage?
It all depends on how many trees you have in an area. If you place enough trees in a small area you will end up at less than 1 fps. Then if you use this method that 1 fps goes to close to 50 fps on a GTX 2080 Super. So it is a pretty big (50 times) fps boost in the case of a high density of trees and shadows that cover most of the screen.
that was great idea - but why u just use the nanite version (same mesh but with other material) but with wpo unplugged on another material ?
I could have done that. We are playing around with how to optimize the Foliage Shadow Imposters to see if we should use Nanite or non-Nanite and what LOD level we should use to get the best performance.
@@SabreDartStudios yeah i get it - great job - i just think we can use one mesh better heheh - nothing more
I agree. Thanks for sharing the idea!
Great job!!!
Commenting for the RUclips algorithm gods. Amazing video 🎉🎉🎉
Thanks!
Amazing but, dude, at that distance you don't get to see the WOP. And, if in the end you are not using Nanite, why not use a different non wpo material for lods higher than 0? or for that matter you could use a material the would turn off WOP at a certain distance from the camera.
Our performance issues were with shadows when you get up close under the trees, not the shadows in the distance. Also, with Nanite Foliage, there isn't really the concept of LOD's, since Nanite self-LOD's. We are looking into other LOD solutions as well though. This was just a first step. Still a lot more to figure out before we have a complete Nanite Foliage workflow for our studio.
RUclips : "Please turn on Mid roll advertisements or we'll punish you in a bad way." 😂😂😂😂😂😂😂😂😂
when I enable plugin in my project and restart cant open project becouse error "---------------------------
Missing Modules
---------------------------
The following modules are missing or built with a different engine version:
FoliageShadowImposters
Engine modules cannot be compiled at runtime. Please build through your IDE.
---------------------------
OK
---------------------------"
any idea?
This was for Preview 2 and you are probably using 5.1 release, so you need to recompile the plugin for your engine version.
@@SabreDartStudios Can you tell me how to do that?
You need to install Visual Studio 2022 and set it up to work with Unreal Engine 5. If you need help doing this, you can contact me on Discord: discord.gg/WK9DhHpT
Hos are the impostors shadiwn the original tree? are there artefacts due to them occupying same space? ohw is it affecting the shadows on "moving" on the wind elements? I don't care for swinging of shadows on the ground but I would like the trees themselves to be properly light and rendered.
The Foliage Shadow Imposter is hidden, so it is not rendered and there are no artifacts. The original tree is properly lit and rendered. The main issue you would run into is that the shadow on the ground doesn't move with the movement of the tree, but that is the tradeoff we are willing to make here.
@@SabreDartStudios hey, that's what i figured immediately when you explained how it works in the video. I guess for very windy weather this isnt a solution, but I guess you always have to make trade offs! I suppose heavy wind is also very difficult to display in games, so that's why you usually dont see it in games. Thanks for the awesome explanation and the plugin!
how do I compile source code in VS, I didn't find any compile or build button maybe due to I opened the wrong file. Can you please tell me which file to compile and how? It would be a great help. Thank you
You can't compile the plugin directly. You have to put it in your UE project and then compile the UE project which will compile the plugin along with it: docs.unrealengine.com/4.26/en-US/ProductionPipelines/DevelopmentSetup/CompilingProjects/
this solution doesnt move the shadows when the tree is moving due to wind - right?
That is correct. That is the tradeoff we are making to get the massive performance gains. The trees continue to move, but the shadows don't move with them.
There is a way to have Unreal automatically disable VSM cache invalidation on materials with WPO that are far from the camera.
It says in the docs,
"In some cases, creating Material LODs that remove WPO/PDO may be impractical, but the end effect of these transformations is small in the distance. Use r.Shadow.Virtual.Cache.MaxMaterialPositionInvalidationRange to set a distance (in centimeters) beyond which cache invalidations from these materials are ignored."
I did not see this mentioned in the video. Have you tried this?
Yeah, we tried that, but the problem wasn't the shadows in the distance that were killing performance it was the shadows up close. The size of the shadow as a percentage of the screen was the main correlation with performance. So the worst performance was when we were directly under a tree. Because of this we decided to make the trade-of of having moving trees, but static shadows. This may not work for everyone, but for our project it is a compromise we are willing to make for the massive performance gains.
What happens if you set the range to something ridiculously low? Would that not result in the same outcome as in the video? Or does it get clamped so that you cannot force the invalidation to be removed completely?
@@SabreDartStudios Is this still an issue now that 5.1 is officially out?
@@MichaelPohoreski This is still broken in 5.1 and 5.2, but in 5.3 it is fixed by setting "Shadow Cache Invalidation Behavior" to "Rigid".
Woah you're some crazy people but with brains full of pure genius!
BUT!
Does this work with the new PCG tool?
Cheers!
I have not tried it yet, but it should work with the PCG tool if you are using the PCG tool at design time.
Great stuff here, thanks for the insightful video. Does your plugin tag the foliage to the same data layer as the hero tree?
It probably doesn't, but that sounds like a really good idea.
@@SabreDartStudios I am running into some VSM issues and likely will try your solution soon, but yea, I'll need to figure how to get the Data Layers sync'd up. I have trees across 3-4 Data Layers. Maybe I can figure out how to do it, or if you update the plugin let us know?
Hello and thank you for this video.
Even if the World Position Offset Distance parameter works in UE.2, your plugin is still useful to gain a bit of performance on animated foliage in the foreground, isn't it? Thank you.
Yes, I originally thought that the new World Position Offset Distance made the plugin no longer required. However, after more extensive testing, for our use case the plugin gets us dozens more fps than using the new setting.
Is there not a command that allows you to set virtual shadow maps to exclude foliage? The idea is for foliage to use the traditional shadow system and static nanite objects use virtual shadow maps. I tested this with non-nanite foliage and nanite ground and rocks which worked. I am not sure if this can be done with nanite foliage yet. This will save you the need to add additional trees.
In the future I expect r.Shadow.Virtual.Cache.MaxMaterialPositionInvalidationRange will work, but as of UE 5.1 P2, this is not working :(
This is an amazing share. Super excited to see all the improvements
Hey folk, thank you for this great solution. for some reason when I click on add foliage imposters UE5 crash 😑. do you have any idea how I can fix it (I am on 5.1.1). thank you
Hmmm, I am not sure. The only thing I can think is that there probably isn't anything stopping it from crashing if the Data Table has inaccurate values. If you jump in Discord we can troubleshoot it: discord.gg/CqvP7cNd
@@SabreDartStudios nevermind I missed one step referencing the data table part.... ☺
Glad you figured it out!
Did you have any performance comparison values for an identical dense forest with and without the shadow proxys?
It just depends on how dense the forest is as to how much the dynamic shadow cost is. With a medium density forest of trees like I show in this video it goes from single digit fps up to around 40 or 50 fps on a 2080 Super. The less dense the forest, the less gain. The more dense the forest, the greater the gain.
While I think this is an amazing solution, and think you did a great job with it, there's one thing that prevents me from using it. I think it only solves half the issue, at least in my case. I've noticed that any moving lights in a scene, such as a day and night cycle, will produce the same issue and cause absolutely massive hits to performance. So it seems like, as far as I can tell, the only thing to do is wait for epic to fix the issue.
Yes, moving lights are always an issue for dynamic lighting systems and Epic cannot fix this. There is an easy fix though. You have to move your lights less often. The way games with day/night cycles do this is by moving the lights in steps periodically. I have a whole video about this, but here is the basic idea. Figure out what your cycle is for day/night (the longer the better). Then figure out the maximum amount of time you can go between moving the light and recalculating the shadows without it looking like the sun in the sky is jumping. If you have a long enough day/night cycle, this can be once every few seconds rather than once every frame. You combine that solution with the solution in this video and it works great in games with day/night cycles like ours.
@@SabreDartStudios Yep, this is exactly what I've done as well. It still gives way more of a performance hit than shadow maps pre-nanite, due to exactly what you've explained in your video. Even setting the rate to every few seconds, you can watch the visualizer as the whole scene turns pure red as it recalculates all the cached shadows. You may be right that it is something epic can't or will never fix. I'll also check out your other video on the subject, thank you for your time and tips.
Can someone here clarify something for me please?
If the mesh for the impostor shadow isn't being rendered, and should net you performance is if it weren't being rendered, how is the shadow being calculated since it has to draw the texture mask and the tree mesh for the shadow?
So is it netting the same performance as if the impostor tree weren't there? Or is there still a performance hit, but obviously not as severe as not having cached shadows?
Even though it isn't rendering the Foliage Shadow Imposter mesh to the screen there is still a cost for the duplicate tree to be in memory and render to VSM. This cost is small compare to the huge cost of invalidating the VSM cache every frame though. This is not the ideal solution. Eventually I expect they will add a setting to either the static mesh or the material to not use WPO when calculating the VSM. But this is all still experimental.
I enjoyed the video :)
By way of a question: if you employ the solution you've proposed, but you have a moving lightsource such as a day-night cycle animated directional light, does this stop being a solution? My assumption is if the trees moving the shadows is killing fps, then the light moving shadows will be the same?
That is correct. If you constantly move the light source (Sun), then it will invalidate the shadows constantly, but this is why games with day night cycles DON'T move the light source constantly. They do it in small chunks. So instead of moving it every tick, you would move the light source every 5 seconds or something like that. You have to adjust it based on your day length so it doesn't look like it jumps in the sky. By doing this it only has to recalculate the shadows once every 5 seconds and so you still get a huge performance gain from caching the shadows for the five seconds in between.
@@SabreDartStudios I see, thank you for the reply :) Would be nice to cache those shadows at large intervals for distance.
incedible
Is it not possible to create an object with both meshes(1 with no shadow and 1 with) so the footage placements rotation would match?
We thought about this initially, but then it would be an actor and I don't think actors work with the foliage tools which are for placing instanced static meshes. We need HLOD performance from the foliage tool implementation of instanced static meshes, so we went this route instead. Eventually Epic will add a static mesh or material switch to fix this issue and we won't need duplicate meshes at all. Until then, this is what we are using.
This kinda is a let down but thank you for going over 5.1 nanite. I have been waiting for this for so long but it looks like it's not ready for a finished product just yet.
Thanks for the plugin. Looks like they've addressed the issue somewhat with PCG in 5.2. You can set the WPO distance for all foliage created procedurally including grass. Explanation here, ruclips.net/video/9DY9Xe1KRW8/видео.html
I have watched your video twice and don't understand why you are using two trees but lovely results👍👍
couldn't you just use a shadow pass switch in the master material?
As of 5.1 release, that doesn't work :(
@@SabreDartStudios Ah that's depressing, I would have run into this issue as well. Just fixed it on my grass by disabling wind, since it's short and photorealistic it's not a huge deal you don't really see short grass move much irl and it's a small trade off for pushing boundaries on rendered geometry count. Still breaking new ground, normal to expect some trade offs but on trees that's huge. Thanks for the plugin, fingers crossed it helps.
What happens if you just used the Shadow Pass Switch in the material WPO to do zero vector WPO in the shadow pass?
A few people have tried that and it isn't working in UE51P2. Maybe it will in a future version. Would be nice.
If I fully understand the concept, this would fail to work once we setup a dynamic sky. Correct?
dynamic sky does make it more difficult, but it does not break this. When you setup your dynamic sky with moving directional light for the sun, it is important to only move the light once every few seconds. Depending on your day length in minutes/hours, you can calculate the longest you can go between light movement updates without seeing the sun jump in the sky between movements. If you look through my videos, I have a video showing how to do this. By only updating the light periodically, the shadows can still be cached between and the performance is still good.
@@SabreDartStudios sounds amazing 😍 you got yourself a new sub
I don’t get it. I have my entire open world map with nanite trees at 80+ fps and no culling distance
It isn't a culling distance issue. Trees in the distance have small shadows and low shadow rendering cost. Trees up close that cover the screen in shadows of multiple overlapping trees have a higher cost when rendered every frame. If you use the VSM Cache visualizer you can see that the shadowed areas are blue instead of green. This is the problem. If there is too much blue on screen, the fps hit is high. With the technique used in this video we turn the blue shadows into green shadows and massively increase fps in certain situations. In other situations with low tree density and low shadow overlaps, the performance increase may be much less.
@@SabreDartStudios oh that’s pretty interesting. Maybe I’ll try that out, thanks.
Heya I just got sent this by a co-worker, have you guys considered just using the Shadow Pass Switch in the Materials instead? You hook the WPO result into it and just tell the shadow pass to not use any WPO = 0.
Unfortunately the Shadow Pass Switch isn't fixing the performance issue in UE 5.1 P2. Hopefully it will in future updates of UE5. r.Shadow.Virtual.Cache.MaxMaterialPositionInvalidationRange is also not working in UE 5.1 P2 to fix this issue.
@@SabreDartStudios ah that's great to know and that's too bad seriously! Would be so much easier to deal with haha 😂
Nice trick, thanks, but its basically rendering both trees? Because i cant get the Shadow Imposter to be invisible in game with foliage tool, there is no "Hidden Shadow" or Actor Hidden In Game", so I end up having 2 trees in one. ( I did not try the plugin, because I need to know first if it hides the imposter despite foliage type? Thanks!
In the imposter (shadow proxy) we set CastShadow to true, bHiddenInGame to true, and bCastHiddenShadow to true. You can do a proof of concept by setting those manually just like I did in this video without using the plugin. If you need any help with it you can contact me on Discord: discord.gg/WK9DhHpT
Great work thank you for sharing :) . I tried on unreal engine 5.1 its doesn't work or its only work with UE5?
Here the message I got when I open my project.
The following modules are missing or built with a different engine version:
FoliageShadowlmposters
Would you like to rebuild them now?
Welp, thank you. Now i know why nanite and all the settings needed to use it kill my fps, everything on screen is blue using cached page visualization mode. The reason tho? No clue.
Can't I make the shadow move using this method?
This method is a performance trade-off where the foliage moves, but the shadows don't.
@@SabreDartStudios Oh ok. So we need to wait until Unreal officially solves this problem. Thank you for comment!
The high cost of moving shadows from foliage, isn't really something Epic can fix in Unreal Engine. Moving shadows are expensive and there is no way around it. What we are doing with this plugin is giving up moving shadows to get a 200 to 300% fps boost, while still having foliage that moves in the wind. Each game will have to decide how much fps they need and what compromises they want to make to get there. For our game, giving up moving shadows to get massive fps gains was an easy choice. For other games, that might not be something you can give up.
hello quick question, how much fps did you have when turning nanite on with 2000 trees when walking inside of it?
yes incredible
Do you know they fix this problem yestarday relase 5.1?
I don't have 5.1 yet, will be getting it tomorrow to test, but I read through the patch notes and they seem to be endorsing my method. Search the 5.1 patch notes for Shadow Proxy or Shadow Proxies.
@@SabreDartStudios "Nanite-enabled meshes now support the Hidden Shadow flag. This allows custom shadow proxy meshes to be Nanite, improving the performance of Virtual Shadow Maps" hmm but how use it?
You use it exactly like I show in this video, except you enable Nanite on the shadow proxy mesh. We gained around 10 fps doing this in a scene with a lot of trees.
@@SabreDartStudios I expect they made it automatic ;/ but thx
thank you so much for this video 💖💖, a question: is this also work with procedural foliage spawner????
I haven't used the procedural foliage spawner in a long time, so I am not sure. It depends on if the procedural foliage spawner uses the Foliage system or not. I don't know.
does your plugin work on offical ue5.1? awesome method btw. :) cheers
Yes. You just have to recompile it for 5.1.
Not sure if Shadow Imposters is the best name, Imposters are already their own thing and often used with foliage. Shadow Proxies might work better, and is the term cryengine uses for a similar approach for shadow optimization.
That is a good point. I was thinking of it as imposter for the shadow caster, but Shadow Proxy probably makes more sense. Interesting that CryEngine does something similar. I expect that Epic will fix this issue with a material setting in a future version and we won't need to use anything like this in production. This video was more just about telling the story we often go through to find solutions. I don't think we will end up using this workflow.
In the 5.1 release notes Epic is calling them "Shadow Proxies", so you were correct about the name :) "Nanite-enabled meshes now support the Hidden Shadow flag. This allows custom shadow proxy meshes to be Nanite, improving the performance of Virtual Shadow Maps."
Thanks 👍👍 Wow
Will this work with foliage placed using a procedural volume?
Good question. I was wondering about this, so I tried it out and it works great. The reason it works is that the plugin operates on Instanced Foliage Actors and it just so happens the procedural foliage volume uses the same thing.
What GPU are you guys using? Granted that if trees are very far and not in playable area then WPO should be removed. Is it me or your diagnostic is wrong here? blue doesnt mean not cached but Static cached, its then dynamic cached only that you lose - red would be not cached at all. As noted in the comments 5.1 as also improved VSM considerably now and allows for hidden shadow nanite mesh, alongside Distance Field Shadows for far distance you should never have to do a trick like this while using Nanite.
The solution in this video is NOT to solve the issue with distant trees. We use Distance Field Shadows to cover distant trees. This solution is specifically to solve performance issues in dense forest when you are up close and under the trees. You are correct, blue is dynamic cached, but it is still way too slow compared to green. In very dense forests we are getting over 1,000% fps increases using the method in this video when up close and under the trees. Now some projects will not be okay with shadows that don't move to match the trees moving, but for the kind of games we make, it is a fair compromise for the MASSIVE performance boost. In the 5.1 patch notes it seems like Epic is endorsing the method we use in this video. They say: "Nanite-enabled meshes now support the Hidden Shadow flag. This allows custom shadow proxy meshes to be Nanite, improving the performance of Virtual Shadow Maps." While I didn't show it in this video, we have now switched to enabling Nanite on the shadow proxies and we are getting an additional 5 to 10 fps in the example project shown in this video. Comments have shared many other ways to try to solve this, but I have tried them all in 5.1 and they don't seem to work. I will be doing an update video soon to show those methods and discuss the Nanite shadow proxies change for additional performance. I am testing this on my 2080 Super and my new 4080. The percentage based fps increase is the same on both GPU's.
They implement this as deafult?
No, this plugin is still the only solution to this problem as of 5.1.1.
@@SabreDartStudios start piss me of this engine, should be time save but nothing work right, no landscape material displacement , poor performance nanite shadows etc
I disagree. These are all experimental features, so it makes sense that all the use cases aren't completely working yet. These are also pretty advanced features that you probably won't find in any other engines.
Is this still needed in 5.1 full release?
I think so. I don't have 5.1 yet, will be getting it tomorrow to test with, but I read through the patch notes and they seem to be endorsing my method. Search the 5.1 patch notes for Shadow Proxy or Shadow Proxies.
@@SabreDartStudios Any update on this? TIA.
They didn't fix it in 5.1.1. I have not had a chance to check 5.2 Preview 1 yet.
Why do not just turn VSM off?
If you turn VSM off you don't get proper Nanite shadows. Our whole world is built with Nanite, so that isn't an option for us.
How do i do that, because im just building a world and am very new to UE, and id rather have shadows that look like Vanilla WoW untill my project is closer to being a game
genius
I can imagine a world in the near future where everyone will be able to make trees with INDIVIDUALLY modeled leaves. Did you know that the average adult oak tree has somewhere around 250,000 leaves? I tried modeling one and ended up with more than two million polygons on a single tree. So yeah, this will be nice, especially with the world-offset stuff in the material pipeline being compatible with Nanite now!
Wow! That is a lot of polys! Nanite is definitely increasing the number of polys we can use, but two million per tree might still be a bit much if you can get close to multiple trees at once. Our testing right now is with trees closer to the 50k per tree range.
It's embarrassing that in 2023 an engine doesn't have these stuff built in.
Not really. This is a new experimental feature (Nanite WPO / two-sided), so it makes sense that all the tooling around something experimental isn't all there yet. As I said in the video, I am sure Epic will come up with a solution for this that is built in, we just don't have it yet.
Or you can wait for a patch 😂. Remember UE5 isn’t ready for prime time yet.
nobody cares about doesn't match it's own shadow, mate, as long ast it's leaves and branches shadows
people will be busy surviving from the enemy in the game
Yes BUT look at how much stuff you have opened........like10 other stuff
Luckily, when you have a 12/24 CPU and 64 GB of RAM, you can usually open up as much stuff as you want with little to no impact :)