Ahh… finally, a break from the beautiful artwork our awesome art team has produced, it’s time to break out the programmer art. I promise this short series of posts will be nice and dry, as I cover our take on Unity vs Unreal Engine, including some of the reasons why we switched from Unity to Unreal for Space Dust Racing, and also some of our experiences with both engines so far. This post may get a little technical in places, so feel free to skim!
Back in the day…
Prior to starting Space Dust Studios, the majority of our experience was working with cross-platform in-house engines. Depending on who you ask, this was both a blessing and a curse. On one hand we often wished the technology was more mature, but on the other hand we were lucky to be close enough to the underlying technology to make changes or add functionality, and were always able to solve any issues we faced.
Moving to a startup environment meant we were faced with a very different situation. We weren’t ready to licence a million dollar engine, and building our own engine did not align with our resources or goals. UDK and the CryEngine FreeSDK – while great in parts – seemed to be severely limited in the kind of rendering technology you could implement on top of them. We needed something more flexible for the type of environments and effects we were looking to create.
I had started looking at Unity 3.5 and after not too long, Unity 4 was out sporting their new deferred DirectX 11 renderer which was architectured in a way not too dissimilar to what we were used to.
The Butterfly Effect video was released at the same time and looked great. It featured their DirectX 11 rendering, with additional features such as physically-based shading, HDR image based lighting, improvements for character animation, hair, skin, clothes and other rendering features (though unfortunately many of these haven’t been released in the 4.x development cycle).
Apart from an underlying inflexible rendering core (which as far as we could tell, doesn’t allow for techniques such as proper stencil-optimized deferred decals, reduced resolution lighting, custom shadow attenuation, TXAA? and you can’t really create your own custom light types or uber lighting shaders – to name a few), there is still a fair bit of leeway for customized rendering, as you do get access to additional render targets, the ability to write shaders, you can modify a few key internal shaders, generate procedural geometry, and it has support for a native plugin system with which you can start calling on the DirectX device directly.
Unfortunately parts of the feature set seemed only surface deep. Many of the DirectX 11 features were not fully exposed and difficult or error prone to get working via a native plugin. We quickly came across the lack of support for floating point textures, 3D texture importing, limited texture addressing & filtering support (UVW), there was support for Dispatch but not for DispatchIndirect, limited support for multiple render targets (we needed 6-8 MRT’s for certain effects but Unity artificially capped it at 4) as well as plenty of bugs, some of which would make it unshippable for us without support or source access to fix them.
“We license Unity source code on a per-case and per-title basis via special arrangements made by our business development team. As this can be quite expensive, we do not generally license source code to smaller operations, educational institutions, nor to companies in countries which do not have adequate legal intellectual property protection.”
An example would be that alt-tabbing in a fullscreen DirectX 11 deferred game would crash when returning to the game. I lodged a report with a test case project via the in-editor crash tool back in Unity 4.0.1f, then checked the issue tracker and sure enough it had been a reported issue back in Feb 2013 but is still yet to be fixed. (I did however recently see an acknowledgement of the issue in the Unity 4.5 release notes so hopefully that one will be fixed in the next release.)
Another example would be a sporadic issue on certain PC’s that meant that before even getting as far as the input/graphics configuration dialog (which happens before we are given control), it would become unresponsive… but not always.
“630 thousand monthly active developers and nearly 2.9 million registered developers”
Thankfully the Unity community is fairly active in the forums (and generally just awesome), so for many of the other bugs we came across, we were not the first and often someone else had posted a workaround for the issue where possible (crashing on exit, add force oddity). For other issues, we knew we would probably need to reimplement a feature in a plugin to avoid them (XInput, I’m looking at you).
There are tons of plugins available on the asset store which have been created by the community. Some are free, some are licensed per seat and others licensed per project. To get set up comfortably, you really need to set aside a good chunk of cash for a bunch of these.
There are plenty of basic features which you end up building yourself and then share between your projects. Better tools to work with prefab hierarchies, a suitable object pooling framework, in-game debug menus and helpers to name just a few. Hopefully the next big release will start filling in these gaps.
In editor footage from an early volumetric rendering prototype built in Unity with a custom rendering extension plugin.
Due to the rendering limitations, we started crossing off features but also wrote a renderer extension plugin DLL to get around what issues we could that way. In order to set up the sampler state as required and provide the support for higher MRT’s and desired formats, we had to jump through a ton of hoops including calling through to the plugin in a fairly delicate way. It was an ongoing concern of ours that future Unity versions could cause implementation issues and would require a redesign or stripping out of features. In practice, thankfully, it made it through with only minor modifications between upgrades and we were able to strip back the plugin a bit as engine bugs were fixed. Alas, with access to the source, it would have been trivial from the start.
There were plenty of positive experiences while using Unity. It was great having diff-able text formats for assets. It was easy to get almost anything started and overall our prototypes came together nicely. Before all the big GDC announcements, I had implemented physically-based shading with planar and captured reflections in Unity, all fairly painlessly and I was looking forward to working in screen space reflections when I got back from GDC.
Footage from our physically-based shading prototype built in Unity. Flicks between two preset times of day.
I’ll leave this post here for now but before I do, I quickly want to mention that as part of the GDC announcements, Unity has announced that they are busy working away on Unity 5 (with physically-based shading and a bunch of new features). We expect it to be a fantastic release when it’s done.
Next time I’ll touch on our adventures at GDC and Unreal Engine 4.