This is the second entry in the series around the visual effects of our narrative roguelite game Crying Suns and, as the game is released on Nintendo Switch, how we designed them. You can read the first part here.
In Crying Suns, you spend most of your time in the command center as illustrated above. But besides the actual characters, the main show of the game remains space. The deep and treacherous space. If something had to look good, that was it. That’s why we took so much time tweaking the render of the various environments until we were fully satisfied.
Artistically Based Rendering
It wouldn’t probably have come as a surprise if I had told you that our depiction of space was not physically accurate. Crying Suns has a very unique and distinctive art direction and, as a 2D game, some very specific constraints in terms notably of readability.
Furthermore, star fields are generally represented as white dots over a pitch black background. It is not by chance that most spacecraft in fiction or in reality are white. First, you can see them on screen, which tends to produce better TV shows. Second, it helps with reflecting light and the heat that could be induced by black materials.
However, we wanted to create a grimmer and darker world. White was not really an option. And even so, as our camera setup looks right towards the stars of the various orbital systems, every stellar object would be backlit, and then would appear mostly black. So we had to find a solution.
The Layers of Space
Even if our artistic vision was clear from the beginning, the process to achieve it was very long and went through several iterations. The render itself takes multiple passes with very distinct goals.
First we basically render the opaque objects, here this big station and the Neo-N cube.
Then the skybox in the background. We may have done it the other way around but this is how Unity does this part.
After that, we introduce the transparent render queue, and especially stars and planets.
At this point, the “regular” part of the render is over. Only remain post-processing effects, like bloom.
That’s generally the moment our producer and narrative designer, Julien Cotret, would say: “Bloom? Are you mad? Do you want me dead? You have to choose, it is bloom or me.” But who needs a producer when you have bloom in your game, right?
Anyway. We’re not quite there yet. The game looks great, but while you can perfectly understand the shape of the Neo-N cube on the right, the station on the left is kinda lost in the darkness of space. The general ambiance is missing something.
Fake It Until You Make It
We need a way for the station to pop out. Something that could emphasize the fact that the station is closer from us than the stars behind it. Something that would be physically inaccurate but that still looks like space. Here comes the “Space Haze”.
We basically designed some kind of radiance that would create a sort of haze due to light scattering when colliding with micro-particles. As of my knowledge, it is not a “real” thing but it looks cool, and helps a lot with image composition. It also adds a lot of depth to the station. Here’s the same effect from a more distant point of view.
The Fog of Space War
How did we make it? As the title suggests, the effect works like a screen-space fog, with a twist: the further you go on screen from the relative center of the star, the less fog you get.
This solution came late in the development of the game. At first, we were using big bill-boarded sprites attached to the main stars in order to simulate the radiance, but it was not as effective and had no effect on the stellar objects themselves.
On the picture above, you can see the radiance around the star that tints the skybox behind it, but the ship and the station do not really benefit from it. They’re “redder” on the faces facing the star, but the other unlit surfaces remain mostly black.
On the other hand, on the illustration below, you can see the impact of the Space Haze effect both on the background and on the objects themselves.
Of course, due to the various types of locations we have in the game (near the sun, far from the star, fights, boss encounters, etc.), we had to deal with different settings for each one and interpolate seamlessly between them as we travel from one location to another.
In order to recreate such an effect in the built-in render pipeline, you mostly need two things : a depth texture and an Image Effect component.
Please note that, even if the overall process should be similar, those steps do not apply to URP or HDRP.
Here are the steps to do that :
- Create a MonoBehaviour harboring an OnRenderImage method using your custom shader for the effect, and attach this script to your camera
- Change your camera depthTextureMode to DepthTextureMode.Depth in the Start method of your script
- Adapt your camera’s near and far clipping planes as the depth texture will be computed based on those values
- Write the damn shader! (Example below)
The following code samples showcase the result of a simple fog shader on a test scene as illustrated below.
Feel free to adapt them to suit your needs by injecting more parameters like we did (in our case the on-screen position of the star, the relative radius, etc).