In video games, beautiful real-time lighting beats heavily in performance, which is especially noticeable on mobile devices. Thus, developers are forced to look for workarounds for this problem.
Lightmapping is a technology that preserves information about lighting in texture, which allows you to free up computing resources for other needs.
In this article I will introduce the reader to the theory of lighting in games, describe the process of creating a “lightmap” in Unity 5, and share some tips.
Over the past couple of years I have had a lot of work with “lightmapping” both at work and on my own indie project. When your team has few production resources and you cannot allocate a lot of time to creating unique graphics for gaming locations, the lighting becomes one of the key factors helping to revive and diversify the picture.
Lighting theory
Reflected light
Let's define the terminology. Illumination in computer graphics is divided, relatively speaking, into two categories:
- Direct Illumination. Direct hit of light rays on the surface.
- Indirect Illumination. Rays are reflected from the surface, scattered and form a soft fill light.
There are many methods for calculating reflected illumination, the two most famous are Global Illumination (GI) and Final Gather (FG). They can be used separately, but together they give a particularly good result. However, you have to pay for everything: the render, that is, the process of calculating complex lighting and its subsequent visualization, will take a lot of time.
')
Global Illumination (GI) is the most “honest" way to simulate reflected light. From the light source photons fly out - particles that carry information about the color and brightness of the light. Hitting a surface, they illuminate it, but lose some of the energy, as a result of which their color and brightness change. Then the photons bounce off and hit the next surface, re-losing some of the energy. This happens several times depending on the settings of the renderer.
Final Gather (FG) scatter points around the stage, - final gather points - from which rays travel in different directions. After a collision with a surface, the rays return to the parent point information about the color and its brightness. Imagine such a picture: the evening, the sun has almost gone beyond the horizon; it becomes dark, but a small part of the room is still flooded with orange sunset light. The final gather point located on the floor sends several rays in different directions, some of them reach the illuminated part of the room and return to the starting point with this information, thereby slightly illuminating the floor with “reflected” orange light. This is not such an “honest” way as GI, but it produces a good result and is often used to fill the scenes with beautiful soft lighting.
For the next picture, I unscrewed the parameters of the reflected light to insane values, so you can clearly see how the light particles bounce off objects.
Ambient occlusion
In addition to reflected light, we are interested in the so-called
Ambient Occlusion (AO). This is the effect of shading in the corners, cracks, narrow openings. Imagine that a beam of light flies into a corner of a room; it is reflected several times from both walls, gradually fading out. The farther into the corner, the less light goes there.
As a rule, Ambient Occlusion is used to artistically emphasize the shading effect - in reality, the rays of light do not lose energy so quickly that the darkness in the corners of the room is as dark as we are shown in games. If you render physically correct lighting, your engine itself calculates the rate of energy loss by a beam of light, and you do not need to render the Ambient Occlusion map (texture) separately. But you can do this if you need to implement the artistic intent.
By the way, it was necessary: ​​some digital 2d-artists love to imitate this effect while drawing, and in general the process of their work is very similar to how they create 3d-graphics.
Texture Atlases
The next term you should know is a
texture atlas . Roughly speaking, this is one large texture, which contains several small textures. Most often, texture atlases are created to save computational resources. Let me give you an extremely simplified example - specialists, hide torches and pitchforks! Let you have a tavern in the game, in which there are 20 wooden objects (tables, chairs, spoons ...), each has its own texture. As a result, the CPU will turn to the GPU 20 times, demanding to render each object separately. If we assign all wooden objects one material that refers to one texture atlas, in which all 20 textures are sewn, then the GPU can render 20 objects in one call (also draw call, I will provide interesting links on this topic at the end of the article).
In the case of “lightmapping,” an additional small texture is created for each object, in which the lighting information is baked. Then many, many small textures of different objects are placed in large textural atlases. As in the case of wooden furniture, we also get a performance boost.
Work with Unity
general information
But back to the lightmap in Unity itself. First of all, be patient and, if possible, a powerful computer. The rendering process has the ability to completely occupy the processor and RAM, so I turn it on before I go to work or go to sleep. Thus, I return to the computer just at the moment when the render is complete.
Looking ahead, I’ll warn you that Unity is caching intermediate lighting calculation results. If you see that you have lost 10 gigabytes of space on the system disk, this is it. To configure the cache, go to:
Edit - Preferences - GI Cache . Here you can specify where it is saved and its maximum size. You can remove the compression, “weigh” will be more, but work more quickly. Here you can clear the cache, but keep in mind that if you have a scene with a ready-made “lightmap”, it will also be deleted, be careful.
5 types of light sources are available in Unity:
- Directional Light . The easiest, imitates sunlight. It is an infinite set of rays parallel to each other.
- Point Light . Point source of light, that is, the rays diverge in all directions from one point. A good example of such a light source would be an ordinary light bulb.
- Area Light . Light source having an area. Imagine a rectangular panel from which the light emanates, and this will be the area light. Such light sources are most often used in offices, shopping centers and other non-residential premises where it is necessary to light large spaces.
- Ambient Light . Fill light without source. Examples of use: light too dark shadows; add atmospheric dungeon, filling it with barely visible light of bioluminescent plants.
- Light Probes . A special light source that affects only dynamic objects. Technically, this is not a source of light, but for simplicity, let's call it that.
In Unity, all objects are divided into
dynamic (dynamic) and
static (static). Static objects are those that are always standing still and not moving anywhere. It is for them that the “baking” of the lighting takes place. Dynamic objects are those that are on the contrary in motion. This includes such elements of the scene as a hero, a monster, a waving flag, a stone falling from a cliff. “Lightmapping” is not suitable for these objects, they are illuminated either by real-time light sources or by means of light probes, which I will discuss in addition at the end of the article.
Parameters of light sources
I want to pay attention to how much the key settings of the light sources (the available settings differ depending on the type of light source):
- Baking . Allows you to select the light source processing method. For “lightmapping,” we put Baked.
- Color . Actually, the color of the light source.
- Radius . Parameter Point Light'a, responsible for how far the rays of light fly.
- Intensity . Just the brightness of the light source.
- Bounce Intensity . Determines the brightness of the reflected rays emitted from the current light source.
- Shadow Type . Defines the display of shadows. I advise you to use Soft Shadows, it gives beautiful shadows at the cost of increased render time.
- Baked Shadow Angle . Only available for Soft Shadows. Imagine a long shadow. The further it goes from the object, discarding it, the more blurred it becomes. If the parameter is set to “0”, then the shadow will practically not be blurred. If set to more than “0”, a blur will appear.
Setting scene lighting
The scene lighting settings window is called via
Window - Lighting , and consists of three tabs:
Object ,
Scene ,
Lightmaps . To start the lighting render, use the Build button at the very bottom of the window. There is also a tick Auto, which automatically starts the render every time you make changes to the scene; use it if you have a powerful computer. More below is information about the number and size of “lightmaps”, will appear upon completion of the “lightmapping” process.
Section - Object
Object displays the settings for a specific object. If you select an element of the environment in your scene, here you will see a number of settings and parameters. Provided that the object is static, there will be a tick on the Lightmap Static checkbox. Most often you will use the Scale in Lightmap field here. As I said earlier, for each object the light is “baked” into a separate small texture, which is then placed in a large lightmap atlas. With the Scale in Lightmap parameter you can adjust how much space this texture will occupy. Of course, the less space is allocated to it, the worse will be the quality of the light “baked” in it. By default it is “1”, but if you know that the object will rarely come into view or it is located far in the background, you can safely reduce this parameter to 0.1 or even less.
Section - Scene
In
Scene are the key settings for rendering lighting. I tell the basics of working with light, and also share the experience of “lightmapping” specifically for mobile platforms, so I deliberately skip things like realtime GI or use HDR texture as a light source.
In Ambient Source, you set up the Ambient Light fill source that I mentioned. You are invited to choose between a sky-texture, a sky of a single color, as well as a sky created on the basis of a color gradient. I prefer to choose Gradient. It allows you to set up three colors - the dome of the sky, the equator and the earth, which will create a rather complicated and interesting fill light for your scene. Ambient Intensity indicates the brightness of this light. Depending on the artistic intent, you can even have a very bright scene lit by one Ambient Light.
The Baked GI tab contains the basic lighting quality settings, both direct and reflected, including GI and FG.
Before we delve into these settings, I want to give one piece of advice. Always keep in mind that by placing light sources on the scene, adjusting shadows and Ambient Light, after rendering the lightmap you will get a completely different picture, only remotely resembling what you did. Therefore, I recommend working with iterations: you expose the minimum quality of lighting to render quickly, look at the result of the render, and then make edits and run the re-render. When you are more or less satisfied with the result, you can improve the quality of the render and enable Final Gather. This will take a long time, so it makes sense to turn on such a render before you leave the computer for a relatively long period of time.
The settings in the Baked GI tab are operated by a unit like texel. Simply put, texel is a pixel, but not on the screen, but in the texture space of a three-dimensional model. But don’t bother with your head - it’s hard to say how Unity operates with texels and how they depend on the scale of the objects, so just move in an experimental way. For example, for my mobile RPG, I make the final ranner with Baked Resolution set to 25.
Texel on WikipediaTexel (short for English
Tex ture
el ement) is the minimum unit of texture of a three-dimensional object. Pixel texture.
The easiest way to explain the meaning of the term "texel" on the example of three-dimensional games. If you come close to the wall in some old 3D-game - (Wolfenstein or Duke Nukem), you can see how the texture of the wall splits into monochromatic squares, which increase when you approach and gather back into a meaningful drawing at a distance. These squares are called texels, and the larger the original texture pattern, the less texels become. For a perfect display of the texture, the number of texels should coincide with the number of pixels on the monitor, but almost all the engines allow the viewer to get closer to the wall than the detail allows.
A source. Below I will talk about each parameter separately, but before that you need to know something else. If you run the render lighting in Unity, then the bottom right will say what the engine is currently busy with. At the very end of the rendering process, Compositing will be written there.
The fact is that “lightmap” is generated in layers. During rendering, several separate textures are created. I don't know which cards Unity does, but among them there is either all or part of the list: Diffuse (direct light), GI (Global Illumination), FG (Final Gather), AO (Ambient Occlusion) and others. After that, the engine takes these cards and merges with each other. For example, it can be based on a Diffuse layer, an FG layer is put above it in Lighten blending mode (just like in Photoshop), and an AO layer is put higher in Multiply mode ... As a result, these layers merge into one picture and the final “ lightmap ”.
Tab - Baked GI
- Baked Resolution . This parameter can be considered the overall quality of the lightmap, which is also Diffuse, as I mentioned in the last paragraph. The higher you put it, the clearer the picture will be. But do not get carried away, there is a certain limit, after which you will not notice any difference. In general, it is important to find a balance between the quality of the “baking” and the render time.
- Baked Padding . The distance between the individual textures on the general atlas. It is necessary so that during compression, when the atlas begins to “float”, the color of one separate texture does not slap another texture. For my game, I usually put in the range of 1-3.
- Compressed . Almost always you will be ticked here, while Unity will compress the lightmap-atlas. In the uncompressed state, they “weigh” indecently a lot.
- Indirect Resolution . This parameter can be considered the quality, or detail, of the GI, FG, and possibly AO layers. It makes no sense to put a large number here, you will not see the difference. For example, if you put 40 in Baked Resolution, then you can safely put in Indirect around 3-8.
- Ambient Occlusion . As I wrote at the very beginning of the article, AO is shading in all sorts of corners and cracks due to the loss of energy by the light beam. This parameter adjusts how quickly energy is lost. The higher the parameter, the darker the AO will be. Let me remind you that AO is an artistic device that actually has nothing in common with physically correct lighting.
- Max Distance . By and large, this is just a blackout distance for Ambient Occlusion. If we take the corner of a room as an example, then at high Max Distance, the darkening will start very early, and at low Max Distance, the darkening will only be at the very depth of the corner.
- Final Gather . Includes the reflected light method described at the beginning of the article. By default, only GI is rendered, and here you turn on FG. Nowhere are there any settings for the number of points that FG spreads around the scene. I suppose that this somehow depends on Indirect Resolution.
- Ray Count . The number of rays that each FG point emits. Most likely, 32 or 64 beams will be enough for your eyes.
Tab - General GI
Let's go through the settings of interest in the General GI tab:
- Directional Mode . A very specific parameter “baking” for each “lightmap” is the second atlas. A regular lightmap is a simple texture, which is then superimposed on top of your objects, simulating their lightness. The second atlas, called Directional, contains information about the direction of the rays of light. It makes sense to include this mode only if you use normal maps and are not working on a mobile game. Otherwise, it is recommended to take Non Directional.
- Indirect Intensity . It can be said that this is the brightness of the layers with indirect light, in particular FG. Earlier, I already told you that a “lightmap” is actually assembled from layers superimposed on top of one another.
- Bounce Boost . Adjusts the brightness of the reflected photons, information about which is contained in the layer with GI.
- Atlas Size . The size of texture atlases with “baked” lighting is indicated here. If you are making a game for mobile devices straight from the 19th century, it makes sense to put 1024 here, since textures of 2048 are not supported by very old devices. Otherwise, I recommend to put 2048, it is supported by almost all devices of recent years. As you understand, the smaller the size of a single atlas, the more they will have to do. If you are familiar with the term Draw Call, then you can easily predict that increasing the number of atlases will hit performance. Therefore, if you do not have specific requirements, try to render in 2048.
Tab - Fog
And finally, fog! Fog, I mean. It has no relation to the lighting renderer, it can be turned on and off at any time. It's all very simple, so take and experiment. Let me just say that fog is an extremely powerful artistic tool. You can radically change the atmosphere of the scene through the fog, thanks to him the sunny scene will become brighter, darker - darker.
In addition, fog can be used as a productivity tool. For example, you want to turn off all textures in the distance and hide them behind the fog. In older versions of World of Warcraft, if you played, you couldn't help but notice how thick the fog was there.
Section - Lightmaps
The third section is the
Lightmaps , where the rendered lightmaps will be located. And if there are many atlases, in the upper part of the tab you will not be able to see all the atlases, the scroll in that window is inactive. Therefore, we look at the bottom and scroll with the mouse wheel.
Here it is important for us to see how full the last, lowest “lightmap” atlas is. If it is almost empty, then either we increase the quality of the lightmap in order to fill the entire atlas, or we decrease it so that the atlas is empty and removed. The picture below shows two well-filled atlas, and one - so far as.
“Lightmaps” are stored in EXR files with a depth of 32 bits.
Light probes
I also promised to tell you about
Light Probes . They are small areas that absorb information about the lighting of the surrounding space. When there are many such spheres, they create a kind of irradiance map of your level or location. They are then used to illuminate dynamic objects in which the light is not “baked”.
To better understand their meaning, I will give an example. There is one Point Light on your stage that has Baked settings, that is, it is used to “bake” the light. You do not do it Real-time, because it is expensive in terms of performance, and many mobile devices do not support such a light source at all. Then you “lightmap” the scene and see that your Point Light illuminates the surroundings. But if you take a monster and place it near a light source, it will remain dark, because it belongs to the class of dynamic objects, and your Point Light only affects static ones.
Now you place a grid from Light Probes around the light source, bake the lights again. And now your monster can walk around Point Light and be illuminated by it! This is an extremely effective and inexpensive way to simulate lighting. To add “samples” to the scene, go to the
Game Object - Light - Light Probe Group . A cube of four spheres will appear on the scene. To select individual spheres, use ctrl + click. Several buttons will appear in the Inspector to add or remove spheres. You can also use the ctrl + D combination to duplicate spheres.
Arrange Light Probes carefully, place them where you want them to absorb the lighting information, and then transfer it to dynamic objects. In order to avoid graphic artifacts and flickering light, make sure that Light Probes form a smooth, beautiful grid.
Below is a screenshot of the correctly displayed grid. If you look closely, you will notice that Light Probes are not displayed in a random order, but are surrounded by sources of light, trying to effectively catch the transition from light to shadow and back.
Conclusion
Finally I want to give advice on creating models of the environment under the “lightmapping”. Creating content for the game, I knew from which side the game camera would look, so for the sake of questionable optimization I deleted the back walls of some objects. At that time, I had the experience of rendering lightmaps, but only in Maya, not in Unity. It turned out that when rendering lighting in Unity, near objects that have holes, that is, distant polygons, hard, well-marked artifacts appear. Keep in mind.
Useful and interesting links
- An explanation of a physically correct lighting and render system written for 3d artists.
- If you want to learn more about draw calls and graphics optimization, then there is a great material for non-programmers - render hell 2.0 .
- On the Unity website there is a good description of their lighting system, sometimes echoing my material.
- In this small note, using the example of Diablo III, it demonstrates how the developer of AAA games uses the same trick - it significantly changes the atmosphere of the levels with one light without changing the environment graphics.