Textures - Cubemap Reflection

From FleshWorks

Jump to: navigation, search

by Judith


Introduction

This is tutorial for experienced T3ed users. I assume that you know the editor basics, already created some new materials and know how to use some image/photo editing software.

Cube mapping is a technique similar to skybox, however, it doesn’t render static background of a level - it is used to capture background around the object and then to put it on it’s surface. In games cubemaps are commonly used to create materials for liquid puddles, brushed and polished metals, glass... in brief any surface reflective enough to mirror its surroundings.

If you want to know more what this technique, please visit this page: http://en.wikipedia.org/wiki/Reflection_mapping

This technique is actually called environment mapping but, unlike the other unreal engines, we can’t modify materials in the editor nor add any attributes to our cubemap. Here you'll see how it is done in U 2.x engines: http://udn.epicgames.com/Two/MaterialsEnvironmentMaps.html


Preparation

Before we start, here’s a list of things you’ll need go through this tutorial:

1. T3editor install.
2. 3dsmax 5.1 install set up to work with the editor.
3. Image editing software with .dds files support (Photoshop, Gimp).
4. Patience
5. Patience
6. A spare evening. Or a day.

Gimp is a free software so all examples will be based upon this application. You can download it here: http://www.gimp.org/ To open .dds files you’ll need the plug-in located here: http://nifelheim.dyndns.org/~cocidius/dds/. All the installation instructions are included in documentation attached to those files.

Ok, if you have the tools ready, probably some level already opened in T3ed, you have to think of a particular object, what would that be? A fancy statue in your house, puddle of water in the streets, or some metal plate in your workshop? If you don’t know and just want to see the cubemap working, you can choose a simple ball, just like in my example. You’ll find it in a mesh browser, it’s the last item in the main folder. Place the object somewhere in your level, possibly in some diverse surroundings, so you can see the difference between all the sides later.

If you don’t have your map an you just want to see it work, subtract a simple cube (512x512x512, for example) and put different texture on every side of it, maybe add some vivid colored lights to make it even more distinctive (remember to use OmniNoShadow or AmbientVertex lights to get a stable performance). Then put the sphere where you want (possibly in the middle of a cube). Ok, looks like you have most of the things ready to prepare your cubemap.


Setting up the editor to capture the images for a cubemap

Unfortunately we can’t capture the shots like folks in other unreal engines, the shortcuts mentioned here http://udn.epicgames.com/Two/MaterialsEnvironmentMaps.html don’t work, besides we have the visibility gem to get rid of... That is why I decided to take the images from the editor, using the Flesh output window.


1. The view

http://www.masterbuilderstore.com/images/cubemaptutorial1/cbmp01_view.jpg

First of all, go to View -> Viewports and change them to floating. Now you have the ability to resize the 3d view window. Grab its upper edge and pull it all the way up, covering the Top View. What you’ll get isn't a exactly a square-shaped window, but it will be enough.

Note: whatever you do from now, DON’T minimize the editor or else your 3d window will revert to its default size!

Ok, rebuild geometry and lightning in your level (if you haven’t done it before) and now let's make sure that there will be no meta-game information appearing in your shots:

- Switch to 3d view and press I (or click RMB on the window gray panel: View -> Show sprites)
- Enable the Flesh renderer
- Turn on Flesh skybox (if your mission is outside and you use it, of course)
- Enable the real-time preview (for all emitter effects to show up)

There’s one little problem left, the plane indicator in lower right corner. While in flesh mode you can toggle the Flesh normals on, so it will disappear, but you might see some strange anomalies in your viewports, stretching grid and green indicators in 3d view. If so, disable it, we'll solve the problem later. Lastly, switch your Front view to Top (and Side to Front if you like, though it won't be necessary.


2. The camera

Right, we have our view set, now we need to change some camera settings, as it works too smooth for our needs now. Yup that’s right, too smooth, you can rotate it freely and it doesn’t snap to grid. Our screenshots must be precise so these features are completely redundant for us now.

Put your camera somewhere near the chosen object (or the sphere static mesh mentioned before) and center your current Top (previously Front) and Side view on it. RMB-click the eye icon and choose Camera properties (or select the camera and press F4). Expand its tree at the bottom, choose Actor. Set EdShouldSnap property to True. Go to Movement, expand Rotation and set all the values to 0. You should see how camera view changed in 3d. Click RMB on the camera icon somewhere in the Top or Side viewport and choose Snap to grid.

Use the grid to move your camera, align it exactly in center of your chosen object (the pivots should match). If the view is obscured, you can delete it for now or use Hide selected actors option. If it's a surface of a puddle or water in the well, center it with the plane on Top view and put it at the same height in Side view. There’s one more thing to be adjusted - level brightness.

Go to View -> Level properties (or press F6) and expand ZoneLight property. Set AmbientBrightness to 32 or to 16, if it affects your lights too much (you should brighten the screens later in Gimp). Now you’re truly ready for the task. Launch the Gimp.

Note: from now on, use only Top or Side view to move the camera! If you make a mistake and move it in 3d view, you’ll have to set rotation properties again!


3. The Gimp

If you haven’t changed anything with your camera, it should be now in place, facing North (the camera arrow in Top view should be pointed to the right). To make a screenshot simply press PrintScreen key and switch to Gimp main window (left panel). Choose the Crop tool and press Ctrl+V to paste the image. Now make a selection and resize it to match the exact size of image captured within 3d view window - it means no panels, borders, etc. Use the zoom in and out (LCtrl + mousewheel up/down) to make a precise selection.

Click LMB within your selection to crop image. You’ll see that height and width don’t match, however the difference isn’t too big (shouldn’t be more like 20 px). Go to Image dropdown and select Scale image. The size of a cubemap is fixed in T3ed and anything more than 512 x 512 px is quite unnecessary, you just won’t see the difference. Actually, 256 x 256 is just fine. Before you set the desired size uncheck the aspect ratio icon on the left and click Scale. Finally, it’s time to save your first shot. For now you can choose any format you like, jpg or bmp for example.

What’s more important is a name of your file. Every cubemap has its textures assigned to walls named by planes: +x, -x, +y, -y, +z, -z. On a diagram below you can see how these planes correspond with directions in actual game:

http://www.masterbuilderstore.com/images/cubemaptutorial1/cbmp01_cubemap_layout.jpg

As you probably guessed, your first shot should be called “cubemap_NegX” or something similar. Save it in some safe place (it’s a good habit to have a separate preparation folder) and get back to T3ed.

Note: it’s useful to leave the camera properties window open with Movement and Rotation properties expanded. If you move camera by mistake you’ll see how the numbers change. However, Rotation is much more important. Judging by the values of Pitch, Roll and Yaw you’ll be sure that you take your shots from the right angle. -32768, -16384, 0, 16384, 32768 - these are the only right values, anything else means your camera alignment is wrong. If so, reset those values to 0, 0, 0 and start rotating again.

Use the Top view to rotate the camera in opposite direction (South). Press PrintScreen again to capture image, then paste it in Gimp and go through the process above (crop, resize), then save it. According to the diagram, this one should have “cubemap_PosX” name. Do the same with East (NegY) and West (PosY) shots.

Good, you should now have 4 images, sides of a cube. In the Top viewport rotate the camera to North direction once again and switch to Front view. Rotate the camera upwards now, until the arrow is a perfect vertical line (this will be easy with camera moves snapped). Crop, resize and save your image as “cubemap_NegZ”. Finally, rotate the camera down, capture, crop, resize and save your image as “cubemap_PosZ”.

If you captured your images with plane indicator on, you’ll have to get rid of it. Clone Tool will be your best friend here. Clean your images before you proceed.


Inside the cube

Now, go to the folder where you saved all the screenshots and open the _PosX file with Gimp. Switch to “Layers, Channels...” panel, in the upper part select the first icon from the left (Layers). You should have something like “main surface” here. Click on it and rename to +x. Drag and drop your _NegX file to Layers panel, you’ll have another surface with the file name. Change it to -x. Repeat the process for all the sides of the cube (of course, _PosY is +y, etc.).

Note: if you want to create a cubmap for a flat surface, you won’t be needing one of the sides. For example, a reflective floor or water puddle does not require the _negZ plane - you can insert an empty transparent layer in Gimp and just name it -z.

Great, now we have all the sides of a cube and by renaming the layers we told Gimp which is which. The problem is, we still have to align them properly within this cubemap. Otherwise you'll see inverted or misplaced images in game.

Before you start working with layers in your cubemap, you may want to make some changes in all of them at once, like changing the brightness: if you set it to 16 it would be wise to brighten the images up. Use Colors -> Brightness and contrast tool.

Next thing you actually must do is to mirror all the images horizontally. This is a reflection, isn’t it? Go to Image (not Layer!) ->Transform->Mirror horizontally.


In a maze of Layers

Now you are working with layers so it's useful to have some specific line of work here, maybe something like that:

- Turn off the visibility (eye icon) on all the layers but the one you want to edit.
- Select the layer.
- Perform the necessary operations.
- Turn off the visibility.
- Turn on the visibility on another layer.
- Select it, do what you need, etc.

You are to perform a set of modifications on each layer individually, all you need is this set of commands in Layer (not Image!) ->Transform menu. Below is the list of a changes you need to apply to your layers:

a) +x: turn 90° clockwise (right)
b) -x: turn 90° anticlockwise (left)
c) +y: don’t change
d) -y: turn 180°
e) +z: don’t change
f) -z: turn 90° anticlockwise (left)


Into the 3dsmax

Wow, you managed to survive this far! Congratulations, you have just created your first cubemap for Thief3. However, don’t get too excited yet, you still haven’t saved it. LCtrl+Shift+S will bring up the Save as menu. This time choose .dds as the extension for your image, give it a name like cubemap_myobject.dds. If you did everything well, you’ll see a dialogue window where you can choose the compression method, but there will be something else as well - “save as cubemap” option available. That’s exactly what we need. Save and close Gimp.

Now that you saved your cubemap, you need to include it in a material definition. I assume that you have already picked/created the diffuse texture for your object. If not, do it now. Then open 3dsmax, go to material library and load your (or create empty) .mat file. Choose your diffuse texture and the normalmap. In Reflection select cubemap_myobject.dds.

It’s time for you to experiment a bit. Pull the Reflection amount slider all the way right (Reflection alpha doesn’t seem to work) save your material and give it a name like “cubemap_myobject_10”. Then pull it to the middle and save it again as cubemap_myobject_5. Add some more variations if you like, use the numbers as an indicator of an actual reflection amount used. When you're finished, save the library, close the window and use the MatExport plugin to export .mlb file. Put it in your T3Ed MatLib folder, copy your cubemap file along with any other textures you need for the material to PCTextures and Textures folder. Start T3ed (or restart if it was still running), load your new/updated matlib file. Use the texture on a selected surface or paint the static mesh (sphere?) with it (left Alt + LMB) and set a new skin for SM (right click on a mesh, Static mesh->Add skin, enter skin name). Rebuild lightning for your level, save it and test it in game.


Addendum - a bit more realistic cubemap reflection

All you did in the tutorial enabled you to create a surface with fake reflection effect, mirroring the surrounding area. Despite it’s complexity the result is still quite crude. You got the surface where everything is mirrored to the same extent, which rarely happens in real world, even if you take materials like glass. To illustrate the problem I took the screenshot of a shiny metal surface with some rust stains, which looks like this:

http://www.masterbuilderstore.com/images/cubemaptutorial1/cbmp01_cubemap_before.jpg

It looks bad, obviously, those stains shouldn’t reflect anything. Can we do something about it? Yes, all we need is to open the diffuse texture in Gimp and make a layer mask. This is how my texture looks like right now:

http://www.masterbuilderstore.com/images/cubemaptutorial1/cbmp01_diffuse.jpg

Now I’m going to create a layermask which is basically a greyscale image, defining the opacity or transparence of your image. Black is 100% transparent and white is 100 opaque. How does it work with cubemaps? It changes the intensity of a reflection on different parts of the image, but without making the image transparent. Black parts just won’t reflect anything at all, white parts will use the full value of reflection intensity. Similar method is used in other engines to define the specularity of a surface.

The easiest way to create a layer mask is to clone your image (Ctrl + D in Gimp), desaturate it, and adjust the brightness, contrast or levels to make a proper distinction between shiny and opaque areas. You can use many techniques here. This is how my layer mask looks like:

http://www.masterbuilderstore.com/images/cubemaptutorial1/cbmp01_layermask.jpg

Now copy your layer mask image to the clipboard (Ctrl +C) and return to the diffuse texture. In the Layers tab right-click the base layer and choose Add Layermask. In the dialogue pick White (no transparency). Paste your mask image using Ctrl + V. A new layer will appear. Right-click it, choose Anchor Layer option. The white Layermask will be replaced with your image. You’ll see that some parts of your image are transparent now, that’s exactly what we need. Right-click your masked layer, choose Apply Layermask.

Save your diffuse texture in DXT3 format, in order to store transparency info. Copy the texture to your PCTextures and Textures folder, re-launch T3ed and load your scene again to see how your surface looks like. This is my material after applying the layer mask, the stains don't reflect anything now:

http://www.masterbuilderstore.com/images/cubemaptutorial1/cbmp01_cubemap_after.jpg


Back to Mission Design Tutorials Page

Back to Main Tutorials Page