Progress Update #19
Orbit Debug/Visualizer Optimization
This week I tasked myself with optimizing the orbit visualizer. The reasoning behind this was that I couldn't render an entire orbit of planets with large orbit radii without the framerate plummeting to the low teens and that would need to change.
Finding the Root Problem
The first thing I set out to do was to find out exactly why the engine was having a hard time with rendering orbits far into the predicted future. While looking for methods of debugging optimization in Unreal, I came across a presentation by the Unreal team on Profiling and Optimization in UE4. This talk introduced me to the stat unitGraph console command as well as the GPU Profile accessible with the shortcut Ctrl + Shift + ,
Through these methods of debugging I realized that the debug line method of rendering would hit the CPU render thread (draw) while the spline method would hit the CPU game thread.
Baseline (0 steps) |
Debug Line (15,000 steps) | Spline (1,500 steps) |
A Third Approach
It seemed that neither method or drawing the orbits was going to be perfect, so I tried looking for a different solution. I found that surprisingly there were many people inline trying to do exactly the same thing I was with visualizing celestial movement. In one of these forum threads someone had suggested using particles, so I made a test Niagara system. It wasn't long before I discovered ribbon particles. These particles are very strange, and I'm still not sure if I know exactly how they work, but from what I can tell they are pretty much in between a debug line and a spline.
With a little tweaking of particle spawning I was able to get a very good result. With 2,000 steps (@ timestep = 1) the furthest planet in the solar system (250,000 units) was able to show a full orbit of the star as well as having enough detail to show the orbit of a moon on the closest planet to the star which completed 5.75 orbits.
But because apparently nothing will ever work perfectly, the ribbon orbit visualizer cannot be shown during gameplay because of the way particle spawning works. I really want to put more time into fixing this at a later date because the ribbons are the most performant out of the three methods, but for now I decided to try to optimize the ones that would work during gameplay.
Optimizing the Debug Lines
I couldn't find anything online on how to reduce the load on the CPU draw thread, which is what the debug lines hit the hardest. Because of this I started looking at what I could to do reduce the amount of prims. As you can see in the first set of pictures the prim count for debug lines jumps up tremendously from the baseline which is what made me think that reducing that number would help.
I tried to figure out how I could render less lines and still get the same effect. This gave me the idea to draw only every nth point. Thus I came up with this solution:
Optimizing Splines
For the splines I did almost exactly the same thing. Only with splines, since they can curve, the RenderedSteps can be even more aggressively turned down because the inherent curve of the spline will fill in the missing information.
With the same settings as the aforementioned debug lines (NumSteps = 15,000 : TimeStep = 0.2 : RenderedSteps = 500) the splines achieve the desired 120 fps mark with general orbits being correct but fine orbits (e.g. moons) being almost completely useless.
I could probably optimize this even more by finding out why/what part of the splines is taking up so much CPU power and trying to disable it, but that will have to be done another time.
Final Code:
Singleton Implementation!
This week I also finally got around to properly implementing the OrbitDebugActor as a singleton. It was pretty simple, with the relevant code being:
OrbitDebugActor.h
OrbitDebugActor.cpp
Line 1 of the .cpp was because I was having a unresolved external symbol error on _instance in the .h and this solution was brought to my attention by a stack overflow thread.
The singleton can thus be used like this:
CelestialGameMode.cpp
Comments
Post a Comment