I finished feral quite a while ago now. As one might be able to guess from the timing of this post, it did not pan out as planned. However, I thought it would still be useful to talk a bit about how the remainder of the project went.
Development up to this point
I want to look at how feral ended up in the context of how I felt it was going to go in previous posts I wrote while actively working on it.
May 2016 – Aug 2016
Feral: Summer Development
Basic DirectX11 framework, art pipeline, and lighting.
It’s much too early to know how well Feral is going to go as a project…We have a solid team and are ahead of the curve by having some work done this summer, so I would say I’m very cautiously optimistic.
Sept 2016 – October 2016
Feral: Engine Proof
Integration with other systems, animation groundwork, skybox, and standalone model viewer.
The team has a difficult milestone ahead in finishing up an editor and beginning to implement gameplay for a prototype
October 2016 – November 2016
Feral: Prototype Milestone
Skinned Animation and split screen.
Our engine is in great shape, we have a month to make a very simple version of our game in it. Although our gameplay is a bit behind, I’m pretty content with our current progress.
I haven’t posted progress since then, but I continued to work on the game and turned it in for a grade for GAM300 in December. I then continued working with the team on the game in spring 2017 and it was turned in again for a grade for GAM350 at the end of that semester.
November 2016 – December 2016
It’s been a while now, so I had to look back on the commit history to see what I was doing at this time. First, I cleaned up the animation code after having just gotten skinning to work recently. I made some changes that better supported an animated model having multiple animations. I also fixed some issues that appeared in the standalone model viewer as team artists used it more. As we got closer to submission, I worked on the graphics section of the technical guide that would be submitted with our project. The last thing I added was sprite text for UI and other stuff.
January 2017 – April 2017
Overview
My involvement with Feral got a little bit more complicated in spring 2017. I had begun working a full-time internship at NVIDIA and thus I couldn’t really take GAM350 and I was already getting Game/Project credit from the internship anyway. So, I set it up so I would be able to get CS elective credit from continuing to work with the team on Feral in my free time. I did this by getting an independent study class that covered the types of things I would want to add to the game anyway. However, it was a bit more restricted than it would be in game in that I had to implement things that were at least similar or in the same specific field as the original plans laid out in the independent study proposal. Because I would be working full time, the team understood that I might not be able to do all the graphics stuff we would need, and I might not be as available to the art team as they would like. So, the team brought on a second graphics programmer take some of my work.
This was a very difficult time for me. I got less done for the game than I had hoped and worked way harder than I expected. I was having a challenging time in both the internship and for my work on the project. For weeks at a time I would go to work, come home, then work on the game till I fell asleep. I would eat in front of my computer at some point. In addition, the other graphics programmer was having issues with implementing Shadows and it took him most of the semester to implement them properly, so I got a bit less help than I would have liked. Nothing against him, I’m not sure what specific issues he was having. Maybe there were integration issues or issues based on the assumptions I baked in when making the graphics framework. This was another aspect of my time in this spring semester working on the game: I was very out of the loop with most of the team. I went to one or two team meetings in the beginning of the semester, but I quickly felt like I only had enough time for my internship and what was on my specific to-do list. My thought at the time was I would do my best with the work I was responsible for and the rest was effectively out of my hands.
Particles
The first thing I worked on in the spring 2017 semester was a compute-based particle system. The system I implemented was based on this GDC talk (https://www.gdcvault.com/play/1020002/Advanced-Visual-Effects-with-DirectX) This was the first time I had ever implemented compute shaders, so I had to learn about them and add compute shader support to my graphics framework. I did implement the bitonic sort described in the paper to support transparency, but I did not implement the per pixel culling. After implementing transparency, I asked my team whether they wanted me to take the time to implement culling for increased performance, and they said they’d rather tone down the particle effects and have me move on to other things.
Glow
The next thing I worked on was glow mapping. This was relatively easy, at least compared to the particle system. I just used an additional two channels on my gbuffer and did a blur. Because I already had compute shader support, adding a simple gaussian blur was very easy.
Animation Blending
The final thing I wanted to work on was animation blending to make the transition between animations more fluid. However, this is where the inflexibility of the independent study came into play. My teacher felt that an animation project was too far out of bounds of the original stated goals of the independent study. So instead, I worked on ambient occlusion as the final project for the independent study. However, I still wanted to implement a very basic form of animation blending that I could potentially build on if there was time. I quickly implemented some very basic animation blending. For every frame in each animation, for every looping animation it can potentially transition to, it calculated the most similar frame to switch to. For example. If the right foot is forward at frame 10 in the walk animation and frame 20 in the run animation, then, when switching from walk frame 10 to run, it will transition to the similar frame in the run animation, frame 20, rather than transitioning to the run animation’s frame 0. This was very quick and easy and did improve some transitions, unfortunately I could not implement a superior solution.
Ambient Occlusion
Instead, as mentioned above, I implemented ambient occlusion because it was more within the requirement of my independent study class. I implemented McGuire’s 2011 algorithm . Although I got it working in time for my class, I did not get it working in time for the game submission. I originally intended for it to be in the game submission, but while working on it, I happened to hop out of my Ambient Occlusion branch to check on something in default. While there, I noticed the performance was terrible. This was a surprise to me. After I confirmed other people were seeing these issues and talked with the designer about when the issues started appearing, I put AO on the back burner because it wasn’t due until a week or so after the game and I started looking into performance, frantically trying to improve it before the game needed to be submitted.
Performance
My optimization was frantic because these problems appeared about a week before the game was due. The game had never been put all together in a level before now and was performing poorly now that it was. I’ll talk about it not being put together until the last week that later. I grabbed NVIDIA Nsight and started profiling the graphics engine. I saw that the thing that was most consistently slowing frames down was a readback in the particle system. The particle system was entirely compute based, so how many particles are currently alive is stored in a gpu buffer. To know how many compute threads I need to dispatch in order to sort the alive particles, I needed to read back the amount of particles that are currently alive. However, waiting to read back this value was significantly slowing me down. So, I just didn’t bother to read back the value and sorted all the particles. Surprisingly, this was a significant speedup at the number of particles that were typically being used in the game, though it was slower in stress situations. Although this helped, I was unfortunately out of time after fixing it to make significant structural changes to the graphics engine. The threat of introducing problems right before submission was too great to do more and the performance was deemed “good enough.”
Retrospective
I would say all in all Feral didn’t end well. Its performance was pretty bad, the graphical quality wasn’t where I would have liked it to be, we were missing a few animations, and gameplay was pretty bare bones. I still don’t 100% know what happened in the spring semester that led to the gameplay and art issues as I was out of the communication loop. However, there were things I could have done make the project better.
Potential Improvements
The first, and probably most obvious improvement I could have made is more communication. It might not have been reasonable to make team meetings every week while working a full-time internship, but I could have been more proactive about reaching out to people on slack about the status of things relevant to what I’m working on. Also, more communication with the other graphics programmer might have helped him implement things more quickly.
The second, and still probably obvious improvement I could have made is more stress testing. A week before the project was due was too late to fix the performance problems. It’s easy to complain and say that the game should have been put fully together sooner, that one week before it was due was much too late. However, it’s still my responsibility to stress test my own stuff. To complain like that would be to complain that the designers did not test my own stuff for me in a sufficient amount of time. The performance problems could have been better mitigated if my tests of systems were more stressing.
One of the main reasons I’m unhappy with the game is that the visual quality could be a lot better, mostly due to very simplistic lighting. I implemented very basic blinn shading as a sort of test of my shader framework back in the summer and never implemented better lighting. Again, I can point to the game coming together in the last week or so, but I should have tested the lighting thoroughly as soon as near finished assets were available, in the mid-spring. I just felt too busy at that point to go back and re-test something that wasn’t on my immediate to-do list or required for a grade. This also shows incorrect priorities. Although glow mapping looks nice, the game would have looked much better if I had instead worked on better lighting rather than glow mapping and ambient occlusion. A concern at the time was that the artists would not have had time to adjust materials to the new system, but I could have done a lot better lighting with the materials I had.
Conclusion
It’s a bit disappointing to work so hard on something that doesn’t turn out as hoped. I think if we had another 4 or even 8 months to work on it, it would have been great, but no one was really interested in continuing to work on it. Although the final project could have been better, it was still a good project for learning stuff. I’d say the project was a success in that I learned a lot about graphics and had the opportunity to work on a decently sized team as well as the opportunity to work directly with artists.
Although this post decently summarizes the project, more info can be found on its project page.