To infinity and beyond – Part 2
January 19, 2012
And now, the second part of Sora’s Story.
After the end of ImagineCup 2011 Contest we were at first sad, but still motivated to try again and give our best. Well, at least at the beginning … later on because of some constraints I was the only one to continue ImagineCup. But nonetheless, I’m still highly motivated.
Starting from 2 weeks after the final of ImagineCup France, I began to develop what would become Sora 2.1.
At the beginning I was very enthusiast about Deferred Rendering techniques allowing an arbitrary number of active lights in the scene (directional lights, points lights, spot lights, …) and planned to make my engine a full Deferred one.
It was actually very promising and worked well on my computer, but at the end it wasn’t the best idea ever for several reasons.
- It has a high cost on Pixel Shaders as Deferred Rendering involve doing full screen passes to compose the lights (at least for directional lights)
- Because of the way XNA 4.0 works, the Depth Buffer cannot be shared between several render targets thus eliminating some optimization possibilities
- To much reading back from the GBuffer (mainly retrieving depth information) can quickly become really slow
- On some older hardware it was virtually impossible to run at a decent framerate (while it ran at 40-60 fps on my computer, on some low end configurations it was running at roughly … 0.1 fps …)
- I didn’t knew FXAA at the time and MSAA is not possible with a Deferred Engine using DirectX 9 (XNA), so everything was greatly aliased …
I then decided to take a leap back and look at what would be the best option for my project. I ended up with a mixed rendering pipeline. The engine is still capable of working in a full deferred fashion, but is also capable of composing a directional light in a forward rendering pass. It can also use lightmaps (from 3dsmax or generated during compilation time using an in-house light baker) and merge everything together. Basically, everything is done as follows:
- The GBuffer for opaque objects is rendered using 4 channels :
- Tone mapped Base Color (depending on the material parameter, including a main directional light if desired)
- Normal, Specular and MaterialId
- Depth and Glow Contribution
- Color Reference, used for the lighting pass
- A lighting pass is done for every dynamic lights in the scene (usually only one, a shadowed directional light)
- Transparent objects are then merged in (only for the Base Color and the Glow Contribution)
- The Glow is extracted, blurred and merged back in Base Color
- After that I compute the HDR luminescence used for Tone mapping (there’s no overpass for my method, the Tone mapping is done directly while rendering the lights)
- Finally Post Effects are then applied (Full Screen Colors, FXAA, …)
Using this architecture I can do almost 60 fps in 1600 x 900 on my computer and it runs at a steady 30 fps (~ 28 fps) even on the computer that was running the engine at 0.1 fps.
But at that time I came into another sort of issues. I started working on a research project involving the Kinect and had to use the Graphic Card to do real-time image processing. But why develop something else when I already have a Game Engine ?
I thus started to adapt Sora with a backend allowing an easy integration with a software project as an Offline Renderer. It can also be used to get a quick access to HLSL processing from C#, I just have to create an instance of my engine and pass in a Shader and some Textures and that’s it. Every XNA and DirectX related stuffs are initialized for me by the Engine.
A Forward Only rendering mode was also included in the Engine (having a GBuffer is really bad when you are just processing images) making it only output the Color channel without any post processing or tone mapping stuff. This mode is technically faster but more limited.
And because everything was working so well, I also used it to compose a 3D scene into WPF to build an interactive software using Microsoft’s Kinect.
With that, the Editor was also improved to look a little more … interesting:
And there it is, Sora Game Engine v 2.1.