This is a small impromptu update about possible project changes…
The main focus of this project is to create a diverse set of game engine ready character from a shared set of custom 2D and 3D building sets. In order to show my character work in the best possible light I chose to use Unreal Engine 4 – for it’s amazing graphical quality, unmatched shaders that combine light programming for extra flexibility and its amazing lighting system.
Only… its lighting system isn’t that great. Well one of them isn’t… we’ll there are two essentially. One focuses on real-time shadows, ambient occlusion and (technically I guess?) global illumination all of which are done through distance-field volumes (that’s important). This makes this lighting method very useful for dynamic settings with lots of movable pieces or characters as it can give a nice visual quality at a low performance cost.
The second lighting method is ligthmaps and lightmass character indirect detail volume. These give the best visual quality at the highest memory and (on the development side at least) computing power. Lightmaps are essentially textures that hold light information that the engine generates as a one-off computation when building the level – this method uses photon paths to crate lighting effects like light bounces much like a ray-traced off-line renderer which can then be streamed over the other textures at a low performance cost once the lighting is built. However as these are static textures projected over objects they do not support moving lights or objects that’s where the lightmass character indirect detail volume come in which is a post-process volume that looks at all the light map data already generated in a space and applies it to any objects that move through it – it’s a lower quality method as it only project processed data that is already there and does not calculate lighting per frame, but when done correctly it can look amazing.
As my characters were going to be stationary inside my environment I originally wanted to use lightmaps on everything to get the best visual quality and performance. However I recently ran into some challenges in getting the lightmaps to work correctly – build times were taking way too long (when the builds didn’t crash) and often resulted in unwanted artifacts. I am currently investigating several possible solutions to this, but given the sheer volume of artifacts present in the end scene have me looking at alternatives.
That’s where the third option comes in – real-time global illumination. It’s a graphics effect that looks at using voxels (in this case) to calculate how light moves in an empty space and then project it onto the appropriate surfaces. The advantage of this is that it can produce the best visual effects for dynamic environment with characters with no need for heavy pre-computing. The drawback is that it can be heavy on the performance. That being said this has been an effect that has been used in games like Crysis 3 (Cryengine 3), Battlefield 3-1 and more recently EA’s Star Wars Battlefront (Frostbite 3). The issue here is that none of these games are base in Unreal Engine 4! Indeed Unreal Engine 4 at release had a voxel based global illumination functionality, which was removed in later versions in favor of the lightmaps solution for performance reasons.
To resolve this I looked at an Unreal Engine 4 version that was not supported by Epic, but instead modified by Nvidia. The Nvidia branch of Unreal Engine 4 has several graphical features that are not supported in the official version like real-time global illumination and HBAO+. This was a particularly difficult process as it called for me to compile my own personal version Unreal Engine 4
*11 hours of compiling, bug-fixing, merging code and recompiling later…
Real-Time GI – note how the light from the projector hits the orange wall, that in turn reflects colored light to the other surface around it.
SSAO vs HBAO+
*Ambient Occlusion is method of darkening the edges of an object to create the sense of complex lighting. There are many different methods to do this, some of which take only edge data from a rendered image, while more advanced models also look at geometry position, angle and distance (currently Cryengine V has the best looking solutions for this)