Sunday, April 5, 2015

Performance Boost and Adding Your Own Objects!

Hey all! It's been a while since the last update. Since then we've put in lerping between the rest of the qualities the spheres have, and have been working with sounds and performance.

Amier's handling the sound, and I'm taking care of the performance.

So without further ado:

Performance!
        When I last blogged about the development, Sphericles ran in-editor around 30 fps. For one object. Even if you weren't looking at it. That's pretty awful. So I popped open the Unreal 4 profiler tool and analyzed which of my calls were taking the highest % of each frame.

         What I found was very helpful. I was calculating a transformation twice and doing silly things, and on top of that I was forming the transform for the caplet triangles into a non-offset space (since they must be relative to the caplet collection object!) and then forming another transform, and going through my entire list of tris and transforming each, again

         I'm pretty sure that's a crime worthy of the death penalty. Anyway I consolidated all the transforming into one transform that is applied to each tri once, which improved the framerate to 60 fps for one object. I stuck a couple more in, and seemed satisfied. That is, until later when I put 50 in at once. The framerate fell below 5 fps. I was mortified, since this program needs to work on weaker pcs, and it didn't even work on my monster of a pc! So, I got creative, and stopped it from updating it's logic at the right times and decreased the number of triangles per caplet with distance. This bumped it up to an almost constant 70 fps, unless you are viewing every single object, in which case it falls to around 40 fps. So, how did I achieve those two optimizations you may ask? Well I'll tell you!

Smart Updating
        By taking the position of a caplet sphere and the camera, I can form a vector from the caplet sphere to the camera. By taking the dot product of the forward vector and this vector, I can get the cosine of the angle between the two! So, if the dot product is less than -0.6, do not run the interpolation logic nor update the caplet sphere's triangles. Also, if there are less than 2 triangles per connection between caplet spheres, I also stop the update logic. 


LOD Optimization
        This was slightly more difficult, but not by too much. Here I needed to draw less triangles based on how far away the caplet sphere is. The "how" was simple: increase the step of the "phi" (remember back to calculating the caplet's connections, I step through phi in spherical coords and draw triangles between the vectors tangent to both spheres). This causes less triangles, and worse image quality, but at the right distances it's invisible. The part of this that gave trouble was finding a good equation for the LOD. I chose Distance*natural-log(Distance)*small-constant, because I needed something similar to a quadratic falloff, so my LOD value would increase a lot as I can see more detail, but be effectively nothing past a certain distance. Dist*Ln(Dist)*const was perfect because it gave behavior similar to Dist*Dist, but not as harsh. 

        The end result of both these techniques is a very smoothly running piece of software, perfectly ready to be used by more people after a couple more performance enhancements. This brings me to the next topic: User generated content! One of the goals of the project is to allow users to make their own content, so we need to support this. The professor we are developing this under says we don't need a true editor interface since unreal's blueprint system along with the functions we made make it easy if not easier to do it there. After some refactoring with inexperienced UE4 users in mind, adding a new object is as simple as making a single blueprint and typing it's name in another clearly marked  blueprint. For example, here's a short video of the process: