Trees Of Daggerfall [PERFORMANCE PROBLEM/SOLUTIONS]

Discuss modding questions and implementation details.
User avatar
MasonFace
Posts: 284
Joined: Tue Nov 27, 2018 7:28 pm
Contact:

Re: Trees Of Daggerfall [PERFORMANCE PROBLEM/SOLUTIONS]

Post by MasonFace » Wed Aug 14, 2019 3:56 pm

Well, I got a few hours to mess around with it yesterday. When I replicated your process to replace the billboard with the Daggerfall Billboard Batched script/shader, I got the same result: you can set it up with the proper archive/index, but once the prefab gets instantiated into the streaming world, the billboard just disappears as if it looses that archive/index information on initialization perhaps?

So, I'm kind of speaking in ignorance here, but from looking more closely at how the terrain flats are rendered in DFU, it appears as if all the billboards in a location are combined into one mesh. I assume since they all share the same material and texture (atlas), this allows them to be rendered in one call without the CPU overhead of dynamic batching. Super efficient. Since we are dealing with LODs and dynamically enabling/disabling renderers in the process, I don't think we can take advantage of the same technique. But even dynamic batching (as apposed to static batching) we should have been getting better performance than what we're currently getting with the Speedtree billboards... so I don't think batching is the problem here - I still believe it is either culling calculations or the crappy Speedtree billboards like you said.

I think your idea about creating a new atlased billboard shader would work just fine. All the billboards would share the same material, so they should dynamically batch into one draw call. I'm pretty bad with shaders, but I think I may be able to copy most of "DaggerfallBillboardBatch.shader" into a new shader that supports texture atlases so we can just reference an index in that atlas for each billboard.

At this point, I want to try one last thing to get Daggerfall Billboard Batched script to work, but I think ultimately we will have to do as you suggest and make our own simple shader and texture atlas. If it comes to that, I can repurpose my Spriter tool to bake albedo and normal textures of the 3D models, then pack them into an atlas. But first, I'll just start with the vanilla textures.
Ok, let me know if you'll need anything.
Can you upload a package with the entire set of temperate forest models? That will give me a good start on benchmarking once I get something working.

User avatar
MasonFace
Posts: 284
Joined: Tue Nov 27, 2018 7:28 pm
Contact:

Re: Trees Of Daggerfall [PERFORMANCE PROBLEM/SOLUTIONS]

Post by MasonFace » Mon Aug 19, 2019 4:43 pm

I was able to prod into this a little more over the weekend. I did a series of tests to try to find the source of the problem.

I'm hoping TheLacus or someone else with more knowledge on the topic than me will chime in and correct any misinformation or faulty assumptions I make below.

At this point, all I know for sure is that dynamic batching is killing performance. We need a way to reliably batch the objects into as few of draw calls as possible. Ideally, we would just set the objects' prefabs to "static" and call it a day, but since the objects all have different materials, there's nothing Unity can do to statically batch them at runtime.

The way it looks like Interkarma solved this with the vanilla DFU assets is to combine all the terrain objects' meshes (probably using StaticBatchingUtility.Combine ?) and using the same material with a texture atlas. That way Unity sees all the objects collectively as one mesh and one material, so it doesn't need to spend any CPU time batching a massive amount of separate meshes into fewer draw calls. The downside to this is that you can't utilize frustum culling or LODs since all the trees are one object and no matter which way you look, you will see it and it will always be close (not that LODs would help with the vanilla terrain flats anyway). I think this trade off is great for vanilla DFU since it saves a lot of CPU time but only adds a tiny amount to the GPU render time.

Now, working with 3D trees with LODs is a completely different case altogether. Whereas the vanilla DFU terrain flats get combined into one mesh, the mod injection 3D Tree prefabs look like they are getting embedded into the terrain data, so I can't directly see what's going on with the individual game objects in the editor in play mode. I would have thought that there would be some optimizations happening behind the scenes that Unity's terrain stuff would do to help out, but it doesn't seem like it.

At this point, I'm pretty sure your assessment has been spot on, VMBlast. A simple test we could have done (and I will do next) is just create a simple billboard material and assign all the billboards to share that one material. If that improves performance, then we will know that creating a custom atlased batched billboard shader is the way to go. It would be great if we could somehow combine all the billboard meshes in the LOD groups into one mesh like the vanilla DFU method to drastically reduce the dynamic batching load, but I'm pretty sure that'd break the whole LOD system. Alternatively, I'm hoping that setting the billboard LOD objects to "static" will have a similar impact.

As an aside, I did notice something about your SpeedTree prefabs. Is there a reason that some of them have a Rigidbody component? Is that needed for wind simulations or something? I removed the Rigidbodies from all of them, but surprisingly didn't notice any increase in performance.

Anyhow, to summarize: I'm pretty sure dynamic batching is what's killing the performance. I think VMBlast is correct that the billboards are not getting batched and that's what's causing the issue. I will try a quick test in the next few days to try to confirm this.

User avatar
Nystul
Posts: 1354
Joined: Mon Mar 23, 2015 8:31 am

Re: Trees Of Daggerfall [PERFORMANCE PROBLEM/SOLUTIONS]

Post by Nystul » Mon Aug 19, 2019 6:02 pm

just wanted to say that I am impressed by all the work you guys put into this. This is the kind of work that is so tedious but so important at the same time ;)
always an interesting read whenever a new post pops up ;)

Post Reply