With Oculus’s recent announcement regarding requirements and specs for the consumer version of their HMD (https://www.oculus.com/blog/powering-the-rift/), I figured it was the perfect time to write that performance bit I teased about the last time around. Let’s see how we’re dealing with optimization on FATED! First, some math to have a clear vision of what we’re trying to achieve.
Know Your Numbers!
FATED is pretty much fillrate bound (http://en.wikipedia.org/wiki/Fillrate), and it’s safe to assume that most early VR games will also be. This is why the following info is important.
A current generation game will generally push about 124 million pixels per second when running at 60 fps in 1080p. FATED is currently running on a GTX 970 (the recommended card for the consumer version of the Oculus) at ~305 million pixels per second.
1920X1080 upscaled by 140% = 2688X1512 * 75(Hz) = ~305 million
The CV1 native resolution and refresh rate looks like this:
2160X1200 * 90(Hz) = ~233 million
Oculus’ Atman Binstock revealed that “At the default eye-target scale, the Rift’s rendering requirements go much higher: around 400 million shaded pixels per second.” After some math, you can figure out that this pretty much means a 130% upscale seems to be ‘the norm’ for Oculus.
2160X1200 upscaled by 130% = 2808X1560 * 90(Hz) = ~394 million
While we don’t have the final hardware yet, we can have an estimate of what it will need in terms of processing power. The closest we can get using the DK2 is by pushing the screen percentage to around 160. This is what we are aiming to achieve!
Trade-offs A.K.A. Battle with the Art Team
Unreal can be pretty daunting when you first enter it, mainly because the engine cranks everything to 11 by default. The first thing you want to do is take a look at what is costing so much and turn off what you don’t need. Sometimes, the art team will hate you for asking to remove that extra post-process, but remember that a vomit-free experience is more important!
With FATED, we decided to go with a ‘stylized’ look so we could remove some of Unreal’s cost-heavy features while keeping the visuals as stunning as possible. We are also making the conscious decision to have each scene as tightly contained as possible. We want to control which objects are seen at each moment (limit draw calls!) and so we design the levels in consequence. These assumptions allowed us to remove some of the features of the engine without overly affecting our visual target. Here are some decisions we made early on:
- No dynamic shadows, everything is baked (with exceptions…)
- No dynamic lights either (with exceptions…)
- Limit post-processes: No DOF, motion blur, or lens flare
Console Command Options
Here are some interesting commands that we used to disable some costlier features:
r.HZBOcclusion 0: Disables hardware occlusion
r.TranslucentLightingVolume 0: Disables translucent lighting
r.AmbientOcclusionLevels 0: No ambient occlusion! It’s a nice feature, but we don’t need it; remove that!
r.SSR.Quality 0: Screen space reflection is also cool, but it’s costly and we don’t need it; delete!
Profiling Limits: Dig Deeper with GPA
At one point, it’s hard to pinpoint what is really happening GPU-side using only the GPU Profiler. To really get a sense of what is going on, we need something to dig even deeper! We’re using a free tool called Intel GPA.
We won’t go in depth on how to use the tool, but there is one important thing to know: it won’t work in ‘Direct to HMD’ mode. So, to start a capture, you need to be in ‘Extend to Desktop’ mode. The quickest way we found to take a capture was to open the editor, set GPA to ‘Auto-detect launched app’, and then run the game in ‘Standalone’.
Now for the Juicy Tips!
Analyze your scene: I talked about the ‘show’ commands and ‘stat scenerendering’ in my last post; this is where you want to use them to determine what your bottleneck is.
Instancing Static Meshes + Foliage: If you have too many draw calls, this could be a life saver! Foliage is especially great if you want to have a dense forest or lots of smaller meshes. But keep in mind that the level of detail in foliage can easily multiply your draw calls. Also, instancing is not always the best option, so make sure it’s really going to help. Don’t hesitate to compare using GPA!
Particle System Bounds: While profiling FATED, I found out that a lot of particle systems we were not supposed to see where being rendered. Turns out the culling of particle systems is not set by default!
Project rendering settings – Screen Clear: This is a minor optimization, but every microsecond is worth it! If you always render something on each pixel (you have a Skybox, say) this is worth setting to ‘No Clear’. Be aware that this should only be set for actual builds, since it will cause weird artifacts in the editor asset viewer viewports.
Project rendering settings – Early Z Pass: This is one of the best helpers for the fillrate. This will do more draw calls, but it’s such a huge help for the number of pixels drawn that it is worth enabling. Some frames got as much as 25% speed gain by enabling that!
Disable post-processes when not using them: We got some really nice post-processes for some features in our game, but they are not always used. Be sure to remove those from the ‘Blendables’ array when they’re not needed!
Shipping Builds: It’s good to remember that your shipping build is going to run a bit faster than your dev build.
We’re always looking for ways to improve performance, and we’re not done optimizing, but this should give you a basic idea of how we’re working on FATED: always profile, add one feature at a time, and look for more ways to make the game run ever more smoothly. There is whole section dedicated to performance in the Unreal 4 documentation (https://docs.unrealengine.com/latest/INT/Engine/Performance/index.html); I highly recommend it to those who want further insight!
Meanwhile, if you have tips to share, or any questions or comments, send them in and I’ll be happy to address them! ‘Til next time!
Mick / Lead Programmer
Reblogged this on The Dungeon Survival Project.
LikeLiked by 2 people
Great post, thanks! How do you implement game logic? Do you use mostly blueprints? And does that have noticeable impact on performance in comparison to pure C++ implementation of game logic?
Hi Felipe, thanks for the comment!
To answer your question, our game is not particularly demanding computation-wise, so implementing game logic in either blueprints or C++ would not really have a meaningful impact on our game performance.
That being said, we mostly code in C++ with events and some limited logic in Blueprints that are created based on our custom C++ classes. For example, we use a lot of triggers in our scene to start scripted events or puzzles logic and pretty much all of those are handled in the level blueprint. All of our game managers have Blueprint versions that are used to easily modify parameters in-editor.
Our level/game designer is the one that is using Blueprint the most as we expose blueprint callable functions in pretty much every gameplay classes so he is able to “glue” everything together.
Hope this answers your question!
Hi Mick, this answers my question, thanks! Is there some gameplay video to see the level of detail that you get with 75fps in VR?
LikeLiked by 1 person
We don’t have a gameplay video yet as we are still in pre-alpha and not ready to show something just yet, but we do have some early screenshots that indicate what the game looks like in this post : http://fatedblog.com/2015/04/01/tips-tricks-from-our-technical-artist-1/
We should be able to get videos and more screenshots soon(ish) so keep following the blog!
Very Interesting read. I produce VR simulations so this will certainly help in my quest to squash motion sickness. As you do, I tested everything when I first got DK2, after a few hours of total amazement I started to feel queazy then it got worse. It took 3 days to wear off and I was absolutely gutted. Couldn’t even look at the headset without my mouth watering (as in feeling sick). This is all on a Mac Pro 6 core with dual D700’s in Windows 8.1.
The fear was obvious, how can I expect to sell my simulations to clients in a VR world if it could potentially make them feel like chucking up. My answer was to throw massive hardware specs at them (Titan X etc) as quality is high on the list but you have given me some tips here that would cost little in time and reduce hardware costs too.
LikeLiked by 1 person
Hi Geoff, thanks for the comment!
Yes, simulation sickness is something we are actively trying to avoid in our game, I also had several unpleasant experience so I understand the sentiment. I never had a case of 3 days (which seems extreme!) but I know different people reacts differently which is why user tests will be extremely important for the early days of VR.
As a VR developer, feel free to comment here on your findings too, this new medium is so young, we need to help each other figure out its intricacies!
Will do. Just to clarify, It wasn’t 3 days of feeling sick more like a few hours but the unpleasant memory of it lasted about 3 days and enough to make me not use the headset. This was due to some demos dropping frames. These things will be ironed out with trial and error though.
Certain areas I am interested in are how we interact with VR without gadgets and controllers. e.g. looking at an asset for a second could pop up a radial menu above it. Rather than expect the user to approach the asset with some kind of controller, the menu could have an examine option which floats it over to the user. Or if this is an immovable asset then float the user over to it, all this is managed by simply moving your head. Anyway, getting a little off topic so will stop 🙂
LikeLiked by 1 person
Great read! Contains some additional commands and tricks that I didn’t write about in my VR Getting Started guide! I’ve added you guys to the guide: http://www.tomlooman.com/getting-started-with-vr/
LikeLiked by 1 person
This post was written in May and unfortunately some of the stuff in here may be a bit outdated. For example, since Oculus removed the Extended to Desktop mode, I’m not sure GPA is of any use (or working at all) when trying to profile the game in stereo.
We just updated FATED to run on 4.10.1, we are pretty much hitting all our optimization targets (fingers crossed) but I’m really eager to try Instanced Stereo rendering in 4.11.