Update 144: 03/11/2019This will be primarily a tech and programming focused entry, providing insight to recent work I've done on the game.
I have plenty of content updates to share, but will save those for a later date
---
PAVING THE WAY FORWARDSince Desolus was built off of many different prototypes over the past several years (as you can see in this DevLog) a lot of the game's tech needed pruning and revision.
Desolus is now in full production, but I needed to take a few steps back to pave the way forward.
As such, in the month, I've been refactoring a lot of the core tech architecture of Desolus.
This really couldn't be accomplished until I was full time on the game, since a laser focused effort was critical in ensuring I did this the correct way.
This update happened in four critical parts:
-Upgrading the Unity Engine
-Rewriting the Rendering System
-Improving the Lighting System
-Scaling the Game to 1:1 Unity:Meter Scale
I'll cover the first three in the following entry.
---
STEP 1: UPDATING UNITYFor anyone who has ever used Unity, you'll know upgrading the game engine's version can be a lengthy and involved process.
For about 2+ years, Desolus has been using
Unity version 5.4.
I held out for a long time, but finally decided to take the plunge to update, since I needed features from future Unity versions.
The Unity version I opted for, was
2017.4 LTS. The LTS is the most critical factor to this, as Unity offers 'Long Term Support' for this specific version.
It's entirely possible I could ship the game on this version of the engine, but I likely will update to a future LTS release, when available. (2017.4 is the only LTS release so far).
Upgrading Unity is a tumultuous process, 999+ console errors is no joke.After holding my breath and upgrading the Desolus project, I was greeted with an exhausting error list.
Fortunately the massive amount of errors were only editor issues caused by ancient code which I was no longer using.
The primary difficulty I encountered, however, was updating my particle system engine to a modern version.
Since my earliest prototypes, Desolus has used TC Particles which is written by
Arthur Brussee.I've been using a custom version of TC Particles since about August 2016, If you want a look at some of the Desolus specific changes, check out
this DevLog.Unfortunately, my custom version was no longer compatible with Unity 2017, and I had to redo
every particle asset in the game. Oof.
However, this did give me the opportunity to upgrade the game's particle engine to a modern version.
Updating Unity took about 2 days of work in its entirety, but was a necessarily evil for the work to come.
---
REASONS FOR REWRITING THE RENDERING SYSTEMOne does not simply rewrite a rendering system in a game. Desolus, in particular, has a fairly complex system in place.
There is some unique shader and camera wizardry to make sure transitions between alternate universes are truly seamless.
The tech person in me was craving interesting problems, but I had to justify rewriting the game's rendering from a project management standpoint.
For some context, the first system took me almost
six months to finish, but I was considerably less experienced then.
The impetus for upgrading the rendering system for Desolus was to incorporate
Volumetric Lighting into the game.
This is an effect which has been seen in recent AAA titles, and offers aesthetically pleasing scenes.
Volumetric Lighting in 2018's God of War. Notice the three dimensional light rays coming from the tree.I planned on integrating volumetric lighting into the game for quite some time, as lighting is a huge part of the art style in Desolus.
However after playing through the new
God of War on my PS4, I felt particularly inspired to do so.
However, integrating volumetric lighting into the game would take quite a bit of work.
I didn't initially plan on rewriting the game's rendering system, but it was a single bug which eventually made me have to do it.
---
THE RENDERING BUG TO END ALL BUGSI have been struggling with a specific 'bug' in Unity for TWO YEARS.
Desolus uses the
stencil buffer to achieve the seamless alternate dimension effects in the game.
This is a buffer which essentially tells the game's camera which dimension to draw on screen (either universe 1 or universe 2).
I won't be going into detail on an explanation regarding the stencil buffer, but there is a detailed tutorial
here which you can check out.
The specific issue I dealt with, is that in Unity you can't apply image effects which have stencil buffer values.
What this means in Desolus is having an image effect applied to a specific universe is impossible.
Among other things, image effects like volumetric lighting wouldn't work between universes.
This was an issue which I first encountered in September 2016,
which you can read about here.Back then I came up with a temporary solution, which I later learned is based on a bug in Unity's engine.
Instead of dealing with that bug and finding a correct way, I opted for an alternate solution.
It came back to haunt me.
Undead bugs coming back to haunt me. (Bug pics from Hollow Knight) The short explanation is, when using
Graphics.Blit when creating an image effect, the stencil buffer gets wiped out.
It even says so in the Unity documentation but gives no example solution (typical Unity):
Note that if you want to use depth or stencil buffer that is part of the source (Render)texture, you'll have to do equivalent of Blit functionality manually
- i.e. Graphics.SetRenderTarget with destination color buffer and source depth buffer,
setup orthographic projection (GL.LoadOrtho), setup material pass (Material.SetPass) and draw a quad (GL.Begin).After scouring the internet for a solution, I found out I answered my own question 2 years ago.... in my own DevLog post...
I also came across this poor soul who asked
the same question in 2014, which I replied to. I came full circle.
The temporary solution I came up back in 2016, and revised earlier this month was this:
In hindsight, unfortunately this solution doesn't 'just work.'This was more of a band-aid to the problem than uncovering a real solution, and predicates on a bug in Unity.
What this ended up causing was a single frame rendering glitch with all stencil buffer effects.
Stencil effects would lag behind for a frame, causing nasty artifacts and a weird ghosting effect.
You can see this ghosting in the above image. For about exactly a frame, the dimension portal lags behind the rest of the scene.
In addition to being visually displeasing, this also broke the seamless transition of the alternate dimensions.
I believe this 'solution' only partially works due to a memory leak from
RenderTexture.GetTemporary.
My assumption is that RenderTexture.GetTemporary allocates a pool of about ~5 render textures and reuses them cyclically.
For whatever reason, I think the stencil buffer from the previous frame's temporary RT doesn't get wiped out.
Note this doesn't work when creating/destroying a normal RT every frame, which implies it is indeed a leak of some sort.
What you are seeing is the previous frame's stencil value. (Just a theory).
One frame! One frame is all it takes to wreck your rendering system.
---
THE OLD RENDERING SYSTEM IN DESOLUSPreviously, Desolus used a single camera rendering system, with some weird shader voodoo magic.
A single camera approach worked for a reasonable amount of time, however has a few disadvantages.
Creating a culling system between dimensions is challenging with a single camera.
To save on computational resources, I had a C# script which would automatically cull objeects in the alternate dimension.
It wasn't perfect, the process was a bit finicky, and processing this script for every object is expensive on the CPU.
There were more rendering bugs than 'THE BUG TO END ALL BUGS' which were tedious edge cases, not easily remedied with a single camera.
Because of issues such as this, I thought it best to create a layered system with multiple cameras.
---
(Continued in next DevLog post)