Start typing to search...

Complete Studio Scene - 03 - Baking The Lights



We’ve finished correcting the problems that originated from the export-import process. So we can begin the real work, to approximate the look of the materials to the original image. First of all let’s remove the realtime light sources from the scene. Enter the Set Importer Options again, switch off the Lights option, and click OK to reimport our model. As we can see everything is turned black except the materials having their own luminosity.


The lightings will be simulated by textures rendered in 3D Studio Max. This can be done with two approaches. One way is rendering Lighting Maps or Lightmaps for short. It is a texture that records the incident lighting at the various points of the surface. It does not embed the material’s textures or colors, it records only the intensity and color of the received light. Using this kind of map has some advantages, it can give a kind of freedom when we set up our materials. But it’s not always easy to reproduce the exact same look that we see on the original Max render.


Therefore we’ll use a simpler approach here. We’ll render the so-called CompleteMaps meaning that the textures will contain the very final look of the objects. These textures won’t need any further operations, they will simply be wrapped on the objects which will look very similar to if we rendered them in Max.


To achieve this we have to create secondary UV channels for the objects which will contain unwrapped UV maps. We’ll render the CompleteMaps using these UVs. By default, in 3D Studio this kind of operation can be carried out through the Render To Texture function. It works perfectly, but has a limitation: we can only generate per object maps. We cannot render multiple objects into a single map. So we have two options. Either we start merging our objects into larger objects - which is not a bad thing since, as we discussed earlier, it can be beneficial performance-wise - or we look after another tool capable of handling multiple objects together.


We’ll follow the second path now. Namely, we’ll use the Flatiron plugin. Here we face some questions. How can we divide the studio optimally? Which objects should we group together into a single map? How big should these maps be? These all need experimenting and reading of the literature. Discussions of these questions are out of the scope of this tutorial. For this particular studio model, I’ll apply a certain division that is suitable for the demonstration of the procedures.


Firstly I want a map for this ceiling part. What’s worth considering here is that this object shares the material with several other wall pieces. Since we’ll have to assign the CompleteMap to a material in Aximmetry, it’s worth considering which objects use the same material to avoid the need for splitting the materials later in Aximmetry. Therefore now I’ll select all the objects using this particular material.


Open the Material Editor and load the material in question into it. Then select the corresponding objects via the Select By Material tool. So this is the group of objects for which I’ll generate a shared CompleteMap. First, let’s generate the unwrapped UV. Choose the Hard Surface mode, it’s more suitable for the selected objects. Set the Target UV Channel to 2. Firstly, we don’t want to overwrite Channel 1, because it contains the UV of the base textures, secondly, Aximmetry expects the UV of the CompleteMap on Channel 2. Let’s make the map size 2K.


Set a name for the group, let’s make it “Walls”. Click Unwrap and we get the desired UV. If we check the modifiers of one of the selected objects, then we can see a new FlatironModifier which represents the adding of the unwrapped UV. Here we can also see the group the object belongs to.


Let’s continue. The next object I want to build a map for is this Midfloor object. It’s merged with this ceiling part, but it’s OK, we can put them onto the same map. The material dilemma comes up here again. This base floor has the same material as the Midfloor. But it is quite large, so wouldn’t be too optimal to add it to the same map. Therefore I’ll generate a separate map for it. This is the situation when we take on a little extra work of cloning the material in Aximmetry later. Let’s generate the UV. Let’s make the group name be “Midfloor”.


And now we select the base floor by itself. Name the group as “Basefloor” and generate the UV.

The next things I want to separate are the curtains. These have a more complicated surface so I select the Organic mode here. Turn on High Quality. Name the group “Curtain” and build the UV.


Now with a bold move, we’ll group all the remaining objects on a single 4K map. First of all, we have to select the remaining objects. There’s a simple method for that. In Flatiron we have the list of the groups we have created so far. Flatiron can turn these into Selection Sets with a simple click of a button. Now we have selection sets for all our objects groups. All we have to do is to select all of them together and then invert the selection - but before that, we change the selection filter so that only geometries will be selected. We have the desired selection now. Name the group “_Others”. Choose Hard Surface mode again and set the size 4K. Click Unwrap. It will take much longer since a lot of the objects will be processed. Here it is.


We can start rendering the maps now. Of course, we have to use the same Render Setup we used when we rendered the image we started with. Except for one thing: in the Renderer group we have to switch off the Reflection and Refraction options, otherwise the reflected objects also will be rendered into the texture which is inappropriate here.


Now we have to specify the kind of map we want to render. We can do that in the Choose Bake Elements dialog. Let’s add CompleteMap. We can render several types of maps simultaneously, but we only need CompleteMap currently. Set its size to 2K. We can leave the filename as is, but still, we enter the file dialog so that we can change the image format. I suggest using OpenEXR format here because firstly it preserves the HDR information in the case we used intense lighting, secondly it stores 16 bits per channel. Also, it uses lossless compression. Click Save. Here we can specify some EXR format options. Choose RGB instead of RGBA since we don’t need the alpha channel. The 16 bits per channel is suitable. It doesn’t really matter but set the Storage Type to Scanlines now. Click OK.


Leave the Map Slot option on NONE. We could add the generated maps to the Max material, either by modifying the original material or creating a shell material. But we don’t want any of them, because we’ll add the map to the material later in Aximmetry. So leave it on NONE.


Let’s set the target path where we want to save the maps. Let’s put them beside our existing textures in the Textures folder of the Midnight Show project, but create their on subfolder names “Lightmaps”. We’ve set plenty of parameters here so far, so we should save the settings. Let’s save them into our project beside the model file. Name the file “Lightmaps”.


There’s nothing left other than actually render the maps one by one. Of course, it can last quite long. If we only want a preview we can do the render with 256 by 256 maps instead of 2K. But now we continue with the final sizes right away. Let’s begin with the Midfloor group. I’d like you to notice that there is a “Single Pass Rendering” option here. If it’s on, the rendering is faster, but in some cases, it gives incorrect results by rendering improper objects into the map. For the Midfloor I switch it off. Then simply click Bake Group. The rendering begins and this would take quite a while, so you might go to the lunch.


Midfloor map is done. Of course, I won’t go over all the renderings. The only one I want to pan out about is the Others map. We have to pay attention because we planned it to be 4K, so before rendering it we have to change the map size to 4096 in the Bake Elements dialog. And in this particular case, I choose the “Single Pass Rendering” option. Click Bake Group. And now you can go ahead and grab some popcorn and watch a full-length feature film.


We’ve finished with all the maps. If we switch to Aximmetry we can check them in the File Browser in the Textures / Lightmaps folder. Since we generated new UV channels for our objects, we have to reexport the scene into Collada. Let’s do it.

Aximmetry has reimported the scene, so we can start to add the new maps. I’d also like to mention an important thing. It’s worth changing the camera motion method in Aximmetry to be similar to the 3D Studio Max one. We can do this in the File / Properties (or Ctrl+E) dialog, in the Scene Editing section. Let’s change Camera Mover System from “Aximmetry” to “3D Studio Max”. In this mode the Max-like middle mouse button movement and rotation is active. Therefore we won’t go mad when we switch between the two programs. Other than that a number of movement functions of Aximmetry remains intact.


Let’s begin with the ceiling. We select its material with the M key, and we see that all walls are also marked since they have the same material. But we foresightedly rendered these into a single CompleteMap. So we simply set the map. As we can see here we could also set a Light Map here, but we followed the CompleteMap method, so we’ll change that one. Enter Textures / Lightmaps and from here choose Walls_CompleteMap. You can switch off the Selection mode to see the results better if you’d like.


We could move on to the other textures here, but the order we begun with is not ideal. We have an Others map that contains all the objects except a few, so it’s far more convenient to assign the Others map for all the shaders, then we set the individual maps one by one on the corresponding shaders. So let’s select all the shaders. Press Ctrl+F to bring up the search panel. Using the Tab key switch to the Type search mode. Type “shader”. Now we have all the shaders in the list. We can mark them all with the Ctrl + right arrow key combination. We unmark the one we already set the map on. It’s the “tv_set_wall” material. Press the left arrow key to unmark it. Press Enter, and we have all the shaders we need selected.


For all of them we uniformly set the “OthersCompleteMap. We can see that it appeared on all objects, and, of course, some of them are correct, some of them not. So let’s continue with the Midfloor group. Select the Midfloor object and press M for its shader. Assign the Midfloor CompleteMap to it. We can see that the midfloor parts and the associated ceiling part are correct now. But the same map appeared on the big base floor which is incorrect since it has its own separate map.


In the next step we’ll address that. Select the base floor object. Here is it’s corresponding module in the Flow Editor. Now we need a separate shader for it which is an exact copy of the original shader except for the CompleteMap parameter. Here the highlighted wire is the one that comes from the original shader. The system has a safety function that prevents the disconnection of the wires that are originated from an imported file by a simple drag. However, by right-clicking on the wire you can bring up a menu, and here you can choose the “Disconnect” operation. We can see that the object has lost its material now. Let’s undo it. We won’t do manual wiring in and out here, because there is a much simpler method. Bring up the connection menu again, and choose “Clone Source Module”. It makes a copy of the source module which is our shader in this case, and at the same time connects it to the same pin.


We can see that the Mesh module has turned yellow. It shows that the module’s connections have been changed. We’ve seen before that a module can turn orange if some of its properties have changed. Yellow is similar except that it indicates the change of the incoming connections. Also, there’s a function to reset the module from this state. Right-click the module and choose “Restore All Connections”, and we see that the original shader has been reconnected and the module has turned back into its original color. Let’s undo it now and continue with the new connection.


Let’s change the CompleteMap in the new shader. The corresponding texture is the one named “Basefloor”. As we can see the floor has changed to the correct shade. But there is something strange here: the gaps between the floor tiles are still wrong. The reason for this is that they are in a separate object in the model and have a separate material. Let’s select the gap object. Here it is. We apply the shader cloning method again and set the same CompleteMap as we used for the rest of the floor. Now the entire floor looks OK.

Only one group left: the curtains. Let’s find their shader as usual, and choose the Curtains CompleteMap. By this, we’ve finished the light mapping of the scene.


After all this a question came up: why did we bother recovering the base textures of some objects, for e.g. the missing wood texture of this column. Why was that necessary as the CompleteMap contains the base texture anyway? The answer is that it’s not always necessary. It’s only important if we plan to light the object with additional realtime lights later. In that case, we get correct results only if the shader computes with the original unlit texture. To see this in effect, let’s add a test light source. Choose a simple Point Light and connect it to the root of our studio model. Move it to the column, and set a way higher intensity. Here it is. When the system calculated this new light source, it uses the base wood texture. And we can spot another thing. The original texture is a rather high-resolution one, so we can see the finest details of the wood. But if I move the light source away so that only the CompleteMap is in effect on the object, then we can see it has lost its details.


That means that this column couldn’t get enough resolution within the CompleteMap. In this situation, we can start rethinking our grouping method a bit. For example, we can generate a separate map for the column, or the column and the other wooden parts together. Now I choose to ignore the problem since from a total view we can’t see the difference.


It’s also worth mentioning that if we follow the Lightmap method instead of the CompleteMap one, we won’t encounter this problem, since the shader always uses the base textures and colors, and the lightmap is only used to determine the amount of the incident lighting on the surface. But as I mentioned, other types of problems can arise, and we wanted to avoid that in this tutorial.


We can spot another annoyance. The image of the rear lamps are incorrectly rendered into the CompleteMap of the glass. But in this case, there’s no need to think of rerendering the maps since this glass surface doesn’t really need any lightmaps. So let’s remove the CompleteMap from its shader. Now the glass became a bit too dark, so decrease the Opacity to better see the lamps behind it. The speculars and reflections will be applied to the glass using another method anyway.

Article content