Greetings reader! The first part of the article on The Light Remake development outlined the process of porting the game to the new version of Unity. I talked a little about the shaders and effects used, what solutions were implemented in working with light, what additional content was created, what content from the old version was reworked, etc. In the second part we will talk about other aspects of development, about post-effects, project structure, working with sound, optimization and other nuances.
Part 2
Post effects
When transferring the project to a new engine, it was decided to leave the old methods of implementing post-effects that were used in earlier versions of Unity. Working with them was more understandable for me and I could make the necessary changes to the very process of image processing.
Gamma
There were not many post-effects in the original game, but one of the most prominent was the color and brightness correction. Then I managed to randomly achieve a pleasant whitish glow and a somewhat cool color scheme. The picture was contrasting and emphasized the fantastic atmosphere of the location. The visual style was somewhat reminiscent of the Battlefield 3 color palette at that time, which seemed to me a very fortunate coincidence.
An interesting nuance is that later, after the original game, I did not manage to completely repeat this effect, there were always some subtleties that made the image look different from the source. In this regard, I decided to change the color scheme in the remake to a warmer and more positive one. The greenery became brighter and more expressive, and the atmosphere became more associated with a sultry summer day. As a bonus, after completing the game, I added the ability to turn on color correction, similar to the original.
Volumetric light
A very important element in this remake is the post-effects associated with light. Older versions of Unity had a very nice Sun Shaft 3D effect. However, its functionality was limited, because it could be tied to only one light source in the scene.
At some point, a very entertaining volumetric lighting effect of Volumetric lights caught my eyeIt allows you to create a very nice, dense glow and rays that can come from different sources. The atmosphere in the scene becomes more voluminous, objects begin to sink into a light haze of air, which impressed me greatly. The only drawback was the high resource intensity of the effect. Nevertheless, I decided to apply it and thanks to Volumetric light, I managed to create a pleasant light from the sun throughout the scene, as well as mystical directed beams of light in certain places: in the hallway at the start of the game, in a room with a sparrow. The effect was also used to emphasize the accents on the lampposts glowing at night, in the episode with the projector, in the boiler room to amplify the light from the windows, in the final scene of the character's ascension to the light.
SSAO and SSR
The other heaviest effects are SSAO (Ambient Occlusion), which creates soft shading in corners and under surfaces, nowhere without it. SSR (Screen Space Reflections) was also added, with which there were many problems even at the development stage. SSR simulates reflections on glossy surfaces, resulting in nice reflections on tiles, metal, etc. The problem is that the effect was very heavy and almost halved the FPS on my hardware. Through some manipulations in the post-effect code, I managed to slightly reduce the quality of the calculation and slightly improve the performance. In general, the frame rate became acceptable, but in some conditions (for example, with Vsync enabled) SSR caused periodic freezes and jerks when the character moved.
Others
In addition to the listed effects, the project also uses Vignette, chromatic aberration, tone mapping, antialiasing, global fog and bloom. For optimization, vignette, aberration and tone mapping have been combined into one process.
By the way, now, when working with graphics, I often recall my personal experience of studying at an art school, where we were taught to emphasize contrasting shadows under objects, display reflexes on the surfaces of objects, and apply a haze on the horizon when working with landscapes to emphasize an aerial perspective. Now I know it was all SSAO, SSR and Global Fog!
How it works?
The original project was assembled literally on the knee. At that time, I did not have any programming skills and all the functionality of the game was built on a few simple scripts. The main one was the Activate trigger script that I found in the standard Unity assets. All functions were based on the fact that the character gets into the trigger, turns on or off certain objects and causes the necessary actions. There was no question of saving or in-game settings.
System
Of course, to implement the remake, it was necessary to write the entire game system from scratch: the control system, saves, settings and in-game mechanics. In general, the competent construction of the project system is still a difficult task for me. Typically, I create a base system object with multiple child objects. Each of them performs its own group of functions and they are all related.
Since the game basically consists of one location, I decided not to bother with loading scenes, prefabs and components, I placed everything I needed in one main scene. Controllers were created that manage everything you need, switch settings, save the game and read the saved data, read the texts for subtitles and notes from a special file at the root of the game, etc. For ease of implementation, as in previous games, it was decided to use the save system in checkpoints. The location contains several dozen interactive objects such as doors, gameplay items, kerosene lamps, etc. For each save, it is necessary to record the object state identifiers, which are usually an Int variable. For example, the door is closed and locked with a key: DoorOpen - o, DoorLocked - 1.I will not go into details regarding the programming topic, since my skills in this area are somewhat specific and superficial, however, they are quite sufficient for implementing my own projects.
Two finals
An interesting task for me was the implementation of virtual scoring to achieve one of the ending options. I wanted to introduce some element of the challenge into the gameplay of the remake, and the idea came to me to connect this idea with the main symbol of the game - with light. It was decided to create a counter that will analyze the ambient light level by several parameters. The ending of the game will depend on how long the player stays in a lit place or in the open sun. The first stage is collecting information from the light probes placed in the scene and their level of luminosity. This parameter is translated into an average and written to a float variable.
Further, the script takes into account the presence of additional light sources nearby, for example, lamps, light from windows, a switched on lantern or lighter in hand. The presence of one of the conditions adds certain values to the already calculated light indicators. And finally, direct sunlight has the most powerful effect on the character. Raycast is shot from a source of sunlight at the character, which informs the system if the player is in the open sun.
All these values are summed up and counted by a counter, which at the end of the game determines what the final will be like. If the player rarely visited the open sky, under direct rays, rarely used a lantern and a lighter, then the final parameter will be low. The system does not always accurately determine the level of illumination, but in general it copes with its task. For debugging and as an additional element, there are spots of reflective paint on the metal pipe in the character's hands, which is an indicator of illumination.
Subtitling and localization
For the remake, a new approach to localization and, in general, the display of texts and messages was worked out. More precisely, this approach has already been used in the 7th Sector project, however, the volume of content there was much less. The method of saving data into a hml document is taken as a basis. All text information for localization is initially stored in an xml file at the root of the game. Messages are divided into groups and are individually tagged, belong to certain categories and certain languages. For a line break, I decided to use the character (*), and to start a new message (#).
At the right moment (when choosing a language and starting a scene), the controller reads all the text information, divides it into lines and separate groups, and writes it to a kind of library or dictionary. Then, individual scripts read this information, for example, when opening a menu or activating subtitles on the screen. The system seemed to me personally convenient and, most importantly, understandable. It allows you to easily enter a new language and make changes to existing text.
Sound
Some of the basic sounds were carried over from the original sources. Ambient, birdsong, movie projector sound, etc. it was decided to leave to preserve the recognition of the project. However, a lot of new content was required. The sounds of the character himself, steps, activated objects, the hero's breathing at certain moments, the effect of a heartbeat, etc. have been added. More variety was added to the set of ambient sounds, chirring of grasshoppers, random sounds of objects falling and slamming doors were added. By the way, I was inspired by the landscapes of the new Half Life Alyx to add the noise of cicadas or grasshoppers, in which the atmosphere of a hot summer day is very cool. I enjoyed listening to and watching Ambient recordings from City17 on Youtube for a while.
Most of the sounds were borrowed from free libraries. Fragments were combined with each other, effects were applied, speed changed, etc.
The creation of the soundtrack became a whole layer of responsible and painstaking work. The compositions in the original project were not licensed, it was a set of tracks by Ludovico Einaudi, composer Thomas Newman and OST from the game “Afraid of monsters”. Nevertheless, we usually get into the soul of what we heard for the first time, for example, the originals of the tracks often seem more pleasant than their remixes, at least for me. In this case, when creating new compositions, I really wanted to preserve the style and atmosphere of the original tracks. It seems to me that the composer Dmitry Nikolaev, with whom we had previously worked on the 35MM game, did an excellent job with this task. I was especially impressed by the new look at the dynamic composition that sounded during the screening of the film in the lecture hall. The track retains the original energetic and slightly psychedelic style,began to sound fresh, but recognizable. By the way, the movie itself was also heavily revised and included a lot of new material. The content for the video was chosen more carefully to avoid copyright infringement, and some of the fragments were created independently.
The link shows the original video used in the original 2012 game.
Although there is no dialogue in the game, there was a place for voice acting. The recording was assisted by Vsevolod Petrykin, who had previously participated in the 35MM project and who gave his voice to the main character Petrovich. His speech can be heard from the loudspeakers at the moment the planes appear, from the telephone receiver in the episode with the launch of missiles and on the radio, on the second floor of the main building.
Optimization
Optimization has become one of the most painful topics and tasks in the work on the remake. It so happened that almost all projects I created earlier on the old version of Unity (4.6) were quite simple in terms of the load on the hardware. The 35MM game on my GTX 970 ran at 200-300 fps in places in fairly complex and busy scenes. The original Light, built on an even earlier version of the engine, showed even higher FPS. But when switching to Unity 2017, the frame rate dropped by 2-3 times. It is clear that the scene has become much more complex, miscalculations of light and reflections, additional post effects, etc. have been added. but I did not expect such a dramatic decrease in performance. The catch is that even after removing almost all the content from the scene, my FPS did not rise above 200-300. This is a half-empty stage, Karl!A lot of work has been done to simplify some geometry, create Lod groups, set up Occlusion culling, etc.
Also, using a script, cameras were assigned a clipping distance for certain layers. For implementation, an example from the Unity manuals was used. Objects of different sizes were assigned to separate layers, which stop rendering if the camera is too far away. Small objects like cans, rubbish, wooden debris, books are cut off after 20-30 meters. Larger ones - after 60-80. All of the above measures have significantly reduced the number of Drawcalls. On average, the number of draw calls in a scene ranges from 800 to 2000 DC. The number of polygons in a frame does not exceed 1 million.
Luminaire clipping
As part of the optimization, a special script was created that, every 2-3 seconds, determined the distance to small dynamic light sources, like kerosene lamps. When the camera was removed from the lamps, the script turned them off so as not to load the system with unnecessary processes. Also, when the character descended into the basement, the source of sunlight was turned off. This significantly reduced the number of DrawCalls.
Few details
- In the basement corridors, standing under the concrete sewer shafts with dripping water, you can see cloudy drops appearing on the screen (character's eyes / glasses). Made simple - provided that the hero hits the trigger and when the camera is directed upwards, the prefab of the particle system with a muddy Grabpass material is turned on. Also at this moment, drops can be observed on the surface of the card if you take it in your hands.
- . . « », . . , .
- , .
- , , .
- . “STALKER ” , . , , . , . , / .
- , — 3 . , , . . .
As you can see from the article, developing your own project is a very laborious process. These are sleepless nights, a constant search for solutions, a search for inspiration, defeat and victory. But, it brings great pleasure and a sense of self-realization. I would say that this is more than just a job - it is a way of life. Our minds are amazing and capable of creating amazing things that sometimes cannot be compared with reality. There is a whole universe in the cranium of any person, and it is wonderful, it is wonderful that this universe can somehow be displayed through your activity, be it a movie or a computer game. Each work is something personal, created through hard and exhausting work, something very important and valuable, first of all for oneself.
I wish you all good luck, creative inspiration and high FPS!