I’m trying out the new Procedural Foliage Spawner in the 4.8 Preview 3
so far it’s great (except for some missing features like placement mask textures), and even the performance is great… until I enable collision.
my setup: my landscape is 6x6km and I’m standing on one edge. the grass is placed via LandscapeGrassType. other tan that I have one tree type.
here’s a comparison shot.
- on the left, the tree with no collision. cull distance of the tree is 300’000, scalability view distance set to Epic. the effective view distance is about 3 km.
- on the right, the tree with collision. cull distance of the tree set to 120’000, scalability view distance set to Near. the effective view distance is about 500 meters
you can see on the left the pure the rendering is a breeze to the GPU, but as as I enable collision (even if I completely cripple the rendering) my PC chokes to death
I tried all the different Collision Presets for the tree, and nothing made a difference.
if it helps to know, I have an Nvidia GTX 970, an AMD FX-8150 CPU and 16 GB RAM
are there any plans to improve this? it’s pretty much completely prohibiting openworld foliage at the moment.
I’m willing to bet that the foliage is colliding with itself, or other pieces of Foliage.
I haven’t tested this yet so don’t know how it works, but is it still based on Channels? It might be worth trying a custom channel that ignores any response to foliage.
well I tried every combination in the collision settings and nothing made a difference. even if I set all Collision Responses to Ignore, the framerate dies when I set CollisionEnabled to anything other than No Collision, which means if the trees have any sort of collision then the performance dies.
I didn’t see any option for Collision Channels on the foliage, so there’s basically nothing else I could do to fix the issue
Epic, pretty please? openworld foliage is unusable at the moment except for purely cosmetic purposes
Have you checked the different STAT viewers to see what actually is consuming the frame time?
Edit: I always seem to click reply under the wrong message…
I’m surprised this doesn’t come with any sort of answer from Epic already
: foliage is far enough from other foliage. plus it’s static meshes anyway. like I said, no setting that I tried made any difference (except turning collision off completely)
jonimake: didn’t try that, but again, it’s just turning collision on or off that makes the whole difference.
the sad part is that even the Kite Demo level has collision disabled for trees and rocks -_-’
This is expected behavior. Collision is extremely expensive as all polygons on the model are forced to draw twice when collision is added, which explains the framerate drop you are seeing when using collision. The reason the Kite Demo trees do not have collision is due to this. There are a number of options available to you to simulate collision, though my personal choice would be to add a sphere collision around your player that is meant to overlap objects. Any object within that area can block the player or you can spawn in a copy of the mesh that has collision set in the same transform, objects outside of this radius have no collision. This will save you on performance while still allowing you to spawn an increased number of foliage objects.
well that’s unfortunate. so anyone that tries to use the new shiny tools for open world foliage will be told that either they use it for purely cosmetic purposes, or has to code/hack their own collision system?
my free time is scarce so my policy is to not do anything that Epic will eventually do, so I have to ask: do you have plans to improve this in the future?
now let’s assume Epic never plans to improve this and I have to make my own system.
if I go for the option of adding a sphere collision around the player, how will it ever overlap with the foliage objects if they have absolutely no collision setting enabled? see my post above - as soon as I enable any kind of collision on the foliage (including just overlaps) it kills my framerate
or maybe you didn’t mean a literal collision sphere, but just finding objects in a radius around the player. wouldn’t that imply I’d have to iterate through thousands of actors every frame (or every N frames) as the player moves?
and besides this option could you briefly describe other options?
Unfortunately off the top of my head I can’t think of any that would work, though I haven’t personally tried to do something like this admittedly. The second option you listed is more what I meant. You’d effectively have to get an array of your foliage actors and do an iteration to find out which trees were within X distance of your controller/character. From there, you can do an iteration to discover which trees need collision immediately as the character/controller is close enough to warrant said collision. This would definitely be more performant in C++ than in blueprints, given the number of iterations and the sheer scope of what you are trying to do. I suppose the only other significantly viable option would be to have collision on the tree, but replace the trees with imposter sprites at a certain distance away from the player character/controller. Theoretically this should help to reduce the load on your machine while still allowing for collision. Admittedly I haven’t done anything with this functionality yet but it is available for use.
hi, thanks for the answer
I’ll have to insist on this question: does Epic have plans to improve this in the future, or is it going to be up to anyone that wants to use the open world tools to implement their own solution for collision?
going back to your suggestion,
initially I’d think that continuously iterating through several hundred thousand foliage instances would be overkill, specially in a multiplayer game (the server would need to also do it for every player to ensure correct movement I think). but if there’s really no better way, I can think of a couple of ways to optimize the whole thing into a usable state
but before I start spending time trying this: can I ask you to ask around, see if someone more technical in these matters can jump in and,
- confirm if there’s plans to tackle this matter from Epic’s side?
- confirm if this would be the go-to solution or if there’d be a better way of doing it?
also this last part confused me:
I suppose the only other significantly
viable option would be to have
collision on the tree, but replace the
trees with imposter sprites at a
certain distance away from the player
this should help to reduce the load on
your machine while still allowing for
I really don’t get how this is relevant. replacing the trees with imposter trees will only help with the rendering (but collision is done in the CPU? reducing load from the GPU so the CPU can do more isn’t really an effective thing). see my pictures above and you can tell the rendering isn’t suffering from this.
also you should know that I’m using the KiteDemo trees, which already have LODs that include imposter versions
Unfortunately this started to get out of my area of knowledge, so I pulled over several of our rendering team members and found a potential solution. In each LOD outside of LOD 0 for your trees, set EnableCollision to No Collision. Enable collision only on the trees closest to your individual actors by utilizing LOD 0’s collision settings. This is why I suggested the imposter sprites, though I have a bit more understanding now of how they work, you’d still have to set the Enable Collision to NoCollision and ensure that they are only set up on your final LOD setting for the objects in question. They drastically reduce the amount of verts that are being utilized, freeing up more processing power for the meshes that do have collision. This will still help as the CPU is storing the data for where the objects are in the world, so it is still handling half the work of the LOD, the other half being rendering itself which, as you said, is handled by the GPU.
thanks for the followup, glad you could ask others about this
so I tried what you suggested, and I see that it helps a bit but it doesn’t quite do it. and it makes me more confused.
I tried unchecking ‘Enable Collision’ for every Element of every LOD, including LOD0, and I was still colliding against the collision primitive of it (the capsule). which I find extremely odd because in theory it should be always using only that - no per-poly collision is enabled so why should it make such a difference, any difference at all?
so now I have my scene with one tree type scattered around the land (an area of 3x4 km), for a total of 47k trees. I set all the Engine Scalability Settings to the lowest, and then I spawn my character and not move the camera. and I get this:
- With all collision enabled in the mesh LOD elements, and foliage set to NoCollision: max 78 FPS
- With all collision disabled in the mesh LOD elements, and foliage set to NoCollision: max 78 FPS
- With all collision enabled in the mesh LOD elements, and foliage set to BlockAllDynamic: max 16 FPS
- With all collision disabled in the mesh LOD elements, and foliage set to BlockAllDynamic: max 32 FPS
number 1) and number 3) is what I reported in the original post btw.
number 4) is what you suggest. so your suggestion seems to help, a bit. I can now collide against the trees and my framerate is “only” butchered to a bit less than half. definately not a way to solve the problem
well that’s interesting. this could very well mean it’s just a bug, which gives me some hope to have a painless fix.
I’ll try it right away, thanks for the information
well I tried it, but didn’t get what you get.
I took my level, deleted all foliage, deleted the procedural foliage spawners, painted the same amount of trees (47k) into the same area, and I get maximum 38 FPS, vs the 32 FPS I get from the procedural foliage spawner version. I can’t tell if there’s anything substantial, or if this difference is merely caused by the different distribution of the trees
then again if I disable collision in the ‘painted’ version I get max 91 FPS, as opposed to the max 78 FPS of the procedural spawner version
also my log is clean
and I checked the stats, and my FPhysXTask averages 16ms in the ‘painted’ version and 13ms in the procedural spawner version
I attempted this on my end and haven’t been able to reproduce this on my end. Joni, I’m going to close your other thread as it would be best for us to continue debugging this on one thread as opposed to two. Does this occur with any mesh? For instance, if you take the simple cube mesh from the starter content and use it in both the painted foliage mode and then the procedural foliage volume, do you see a significant decrease in FPS or is it only when you are using objects such as the kite demo trees?
I tried making a test map out of the blueprint FPS template project, but I’m getting perfect performance with the cube meshes as procedural foliage. No log spam or anything and stat physics shows that the physx task is performing well. I’ll keep investigating and checking what might cause it.
If I can’t figure this out, I’ll probably just host the project with which I have problems somewhere and share that to you.
I didn’t use the kite demo trees, I used the free pine speedtree sample. But I just tested those trees in the new project and the performance difference between collision and no collision is zero. Could it maybe be related to the pawn/character?
it may be specific to the meshes used. I’m going to install the kite demo on my end and attempt this specifically with the kite demo assets. I believe it may be specific to the amount of polys that are being rendered with collision all at once but this will allow me to determine with some level of confidence whether or not that is the case.
I haven’t been able to reproduce it myself in a new project. I suppose the only odd thing in my original project is that physics stop being simulated (or something, this is when the physx task takes two milliseconds) when my character is still and I don’t rotate the camera around. I’m guessing this is some sort of optimization? I wasn’t able to reproduce that behaviour in a new project, physx task took 9 ms with 170k foliage instaces regardless of my controlled character being completely still.
Kinda off topic: Any chance of performance improvements for this from Epic or Nvidia? Or are there some kind of variables in the engine code that we could modify to make physics more suitable for large physics body counts? It’s kinda jarring that the new instancing system allows us to render the huge forests and worlds, while CPU performance with physics being the bottleneck.
well the performance is nice without collision and horrible with collision. your question is not off topic, it’s what I’ve been asking for since the beginning