Color enhancement, particles and shaky cams
Hello everyone! We are here another month to show you how things are going in the studio. We spend some time working on the use and application of colors, tints and shades for the characters and scenarios, trying to approach the original concepts made outside Unity. We’ve been experimenting with particle systems too and worked in other technical issues like improving the loading times between stages. Want to take a look?
Level color grading
Since the beginning we wanted to design the different elements that shape the game (scenarios, objects, lighting effects, characters) without color restrictions, avoiding the 8/16-bit retro palettes characteristic of the pixel-art aesthetic.
Certain materials like metal or cardboard use a consistent color pattern on different objects, but our priority was to create every element with its own tones and shades. Although this is not a problem in itself, it is true that all these graphics can be dissonant with each other as they are not affected by the global lighting and refraction of color of the different stages and elements (such as tinted bulbs/glasses, fire, water…). In order to unify the hue range without losing their original colors we applied tonal curves and adjustment layers previously generated in a raster graphics editor.
To import these adjustments on Unity we use an asset called Amplify Color that helps to blend the tones of the scene and obtain an homogenous look for each stage. This extension is really easy to use, the only thing you have to do is generate the hue/saturation/color curve you want in Photoshop and link the image generated with Unity. The results are astounding and it doesn’t even affect the game in terms of performance.
Here are some examples of color grading. As you can see the colors stand out and the color curves manage to give a cohesive look to the different entities that conform the scene.
Color blending options
Leaving the level color grading aside, we needed to develop ad hoc shaders to tint certain zones of the scenarios and objects/characters depending on specific situations. The question is: Why don’t you apply the color grading asset on individual elements? The answer is simple: unfortunately, Amplify Color doesn’t apply this effects to isolated sprites. The extension picks the original adjustments made outside Unity and adds them to the whole scene (in brief: to the game camera), so we can’t obtain adjustment effects on determined spots/elements.
To this effect we managed to integrate Color Fx shaders that are similar to the layer blending options of raster programs like Photoshop or Gimp, considering that we can’t accurately reproduce adjustment effects such as curves or color balance to individual sprites.
On this example you can see the steps made to change the overall lighting of a scene. Each element has a specific shader with a blending mode. The curve adjustment is the last one applied and affects the whole group of layers behind.
The math behind the blend modes
We implemented various typical shaders to apply individually or as layers, this way we can recreate some effects otherwise impossible for us.
Additive: an additive shader does what the name implies, it adds the color passed through, or the color of the layer, to the original color.
If "o" is the original pixel and "c" is the color you’re applying the function will look like this:
f(o,c) = (o.rgb + c.rgb) * o.alpha
Multiply: multiplies the color passed or the one from the layer to the original color:
f(o,c) = (o.rgb * c.rgb) * o.alpha
Tint: this one is more complex, we convert the RGB components of the original color and the color being applied into HSV, then we calculate the resultant RGB like this:
cHSV.brightness = oHSV.brightness * brightnessProperty cHSV.saturation = saturationProperty
o.rgb = ConvertToRGB(cHSV) * blend + o.rgb * (1 - blend)
Where oHSV and cHSV are the original and new color RGB componentes converted to HSV, brightnessProperty and saturationProperty are variables to determine Brightness and Saturation respectively, and blend is a variable between 0 (none) and 1 (full) to control color blending.
Creating contrast and depth
Throughout the development we noted that in some areas like the laboratories wich have a big set of on screen elements -such as servers, research equipment, tables, monitors and more- were difficult to differentiate the characters from the environment. Also, interactive objects didn’t stand out from decorative ones. To solve this problem we added a gradient shadow in some stages between the interactive and decorative layers. Now players will be able to spot platforms, scalable objects, buttons and hideouts more easily.
A lot of Paradise Lost elements are volumetric shapes like smoke, fire, water, electricity sparks... When we started the project those effects were made with traditional animation. Seeing the amount of work needed to obtain realistic effects, Carlos proposed to create a particle system that allow us to include particles with a pixel art look, adding dynamic behaviours to this elements and saving development time. This is an example of the particle system added for effects like energy flakes or smoke.
To obtain a pixel art look we imported pixel sprite particles of different shapes, showing jagged columns that follow the same aesthetic of the game. The different parameters allow us to change the density and frequency of the particles emitted by the different objects.
This is a sample of the dynamic particle behavior, attached to a thrown gas bomb:
As of late we felt that the damage perceived by Subject W wasn’t too obvious (with tons of elements on screen and a discrete HUD this was a problem in some circumstances), so we worked on a system to show the impacts in a more clearer way. Most games add a tint effect in the borders of the screen, but it looked too annoying and overlapped, so we decided to include a little shake to the cam. We don’t want a dizzy/blurred effect so we added a controller on the editor to regulate the effect if needed.
The issue with loading times was clear since the demo, they were too long for being as frequent as they are. So Carlos tried to find the reasons behind the lenght of the loading screens and how to solve them. The solution was pretty obvious and one of those things that ended up being far more simple than expected.
When the game enters in a loading screen, the screen fades to black, then loads the room, then the audio switches if necessary and lastly the screen fades again to the game. The problem lies in the amount of time spent on fading the screen and switching the audio, it was too long, and it was something we put there, we set the speed for the fading and the switching, so when pumped up the loading screens were cut in more than half the time, leaving the loading almost instant.
We think it’s possible to shorten the time even more with a few tricks Carlos has in mind, is something that we’ll address ASAP.
And that’s all for this month! We’ll keep you updated with more progress in the near future. In the meantime don’t forget to enjoy the wonderful Hyper Light Drifter, one of the big indies out there.
PS: for those who played the game... have you found Subject W already? (・∀・)