Recently in my post-mortem for our What Thou Art game jam I shared with you a material which I modified using Substance Designer. I wanted to delve deeper into how I’ve been using Substance B2M and Substance Designer 5 to create great-looking PBR textures for use in Unity.
The Substance software suite is a PBR material workflow from Allegorithmic. Substance enables developers to quickly and intuitively create materials that work with a variety of engines (Unreal, Unity, etc.). I’ve primarily used Substance B2M and Substance Designer, both of which can work together to create base materials. Also in the Substance suite is Substance Painter – which enables materials to be ‘painted’ onto a model’s UV maps. I have very limited experience creating 3D models and haven’t needed to use Substance Painter yet (but I know it’s only a matter of time). Allegorithmic touts that Substance is used by “80%” of the industry at large – by companies like Naughty Dog, Epic Games, etc. in their triple-A titles. Lastly, Substance provides a free year of the Substance Suite for every year in which you are a student – which I think is very useful.
PBR stands for Physically-Based Rendering. PBR materials are materials which interact with in-game lighting and reflective effects to create realistic shading and lighting. A game engine interprets materials like layers with very specific filters. For example, common materials in a game will have several ‘maps’ (consider them like layers): your base-colour/diffuse material, a normal map, a roughness map, a Heightmap, and an Ambient Occlusion map. You might be able to get away with diffuse and normal maps only for a material – but proper PBR looks best when it can interact with light and reflective objects throughout the scene. By no means are the above five materials the only materials you can use in a PBR material; they’re the ones I regularly use. The game-engine interprets the material in each frame like so:
- Diffuse/Base-Colour materials are the ‘base’ colour of the material. Base-colour where all the colour information is stored and modified by the other maps in the material
- Normal maps are very common types of maps. Normal maps are textures which tell the engine which texels (pixels on a texture (a synonym for ‘map’) are facing a direction. Using three colours (green, red and blue) the engine interprets the colours to determine where in three axes the texel is facing. Normal maps are very useful for creating convincing light and shadow effects on completely flat textures. Instead of rendering a brick wall, you can use the normal map to calculate the appropriate shadow and light effects that look convincingly realistic. Normal maps are limited to only light and shade, and will not cast shadows onto itself – only darken the texels.
- Roughness maps interpret which parts of the material are rough and smooth. On a scale of black (smooth) to white (rough), the roughness map will add reflectiveness to darker areas of the material. Remember – this map is abstract and stores no colour, it simply informs the engine which sections of the texture are reflective and which aren’t, and how reflective they should be in between.
- Height maps are maps which inform the engine how “high” sections of the material are from the “base”. Like a Normal map, the “height” map enables the game engine to interpret the height axis to perform specific effects. Unlike Normal maps however, having height information allows for some special shaders which give the impression of depth. When using Height maps in Unity, Unity will apply a POM shader to the material (Parallax Occlusion Map) which will effectively ‘sink’ the texture into itself based on the relative height, to give the impression of a 3D material.
- Ambient Occlusion maps are the final and simplest type of map I use. Like Ambient Occlusion in 3D environments, AO is designed to shade right-angled and occluded areas to give an impression of Global Illumination with a fraction of the performance overhead. This principle works similarly for the AO map. Applying an AO shader to a material will inform the game engine that this material is darker than its surroundings – regardless of the light cast onto Using an AO map is a simple way to add shadows to areas without putting them into the base-colour.
- There are many other materials within Substance which I don’t use and won’t touch on.
By no means is my workflow perfect – it isn’t. The process of taking a material through each stage isn’t intuitive and has its advantages and disadvantages, which I will elaborate on later. I’d love some feedback on how to streamline my processes.
Substance Bitmap2Material is a straightforward program which enables the user to convert Bitmap images into Materials. Substance B2M – for me, at least – is a game-changer. I can take photos on my phone of materials I see day-to-day, and B2M will break the material down into all of the different maps that I will use later on.
Firstly, I took this picture recently of a concrete wall at my university. It’s notably dirty – but the image is evenly lit and has applications in any game with concrete walls. When taking photos for use in B2M, they should be evenly lit and straight (but you can straighten them up in software on a phone or any image editor). When taking a picture, be careful with any lens flare or distortion which may impact the final image, as well as avoid sharp light/shadows onto the material. Furthermore, take a photo of the least interesting part of the material. When taking a photo of grass, make sure that there are no identifiable markings on it (like cigarette butts). You want the image you shoot to be as ready for prime-time as possible
Should I crop my image into a square?
I usually do this to crop out identifiable areas (for example, cropping out a patch of grass when I just want the dirt), but it isn’t necessary since Substance will crop them for you (it may not crop the right part!)
By dragging your material into the editor, B2M will immediately interpret your image and split it into Base-Colour, Height, Normal, Roughness, Ambient Occlusion. If you don’t need these materials or you need others, the bottom Output menu will allow you to remove them.
By default, B2M will suck some of the luminance out of the base colour, which is very useful because the base-colour should not keep any lighting information (the game engine will provide the light). I usually maintain the values of the base colour the same, but B2M’s most compelling and useful feature is Make It Tile.
Make It Tile is a tool to let artists make their materials tile convincingly. Game engines will tile materials to cover a wider area than the texture is built to stretch. Making a texture tile isn’t easy – each side must blend seamlessly into the other side. Luckily for us, Make It Tile does this for us. Make It Tile uses 5 blending modes to do so: Edges Quincunx, Edges Linear, Edges Y, Edges X, and Random. I prefer to use Edges Linear These tile methods give a variety of blending modes to the horizontal and vertical edges. I generally enable Make It Tile straight away and Make it Tile will immediately recalculate all of the materials that diverge from the Base Colour. Thankfully also, Make It Tile isn’t destructive, at any point you can change modes or disable it without losing your original unblended base colour and materials. Within the Global menu, you can also adjust the tile transition size (below), to give the texture more space to blend the textures.
The end result will look something like this (left). The darker areas are an artefact of the Height and Ambient Occlusion effect, which we will fix later
Managing Normal and Height maps
When working with Normal maps, as the artist of your material, ask yourself what your materials “height” is. Is your material meant to be flat, relatively flat, or bumpy and defined? Firstly, I go into the Normal Intensity slider and adjust it to be appropriate for the material. If you are observing the material in the 2D view, you can see the Normal map’s range of colour. The more intense the Red, Green and Blue areas, the more pronounced the material’s “bumpiness” and definition is. For the concrete wall we have created, we still want the lighting detail, but no more than necessary so that I will keep the Intensity at 4. For very bumpy surfaces such as rocks, It may be appropriate to set it at 16-32. As you use the slider, observe the 3D view to verify that the lighting interaction is appropriate for your material. Because Normal and Height information is intrinsically linked, both materials are affected by adjusting values in the “height” menu.
The strange darkened areas are a result of the height information being misinterpreted. Within the relief menu, we need to adjust the tolerances for it to even out and receive the actual definition we need. Set the Low Frequencies to -1, the Mid Frequencies to -0.5, and the High Frequencies to -0.275. You should observe how the height definiton reflects the actual ridges in the cement.
Roughness is a little trickier to get right. As above, Roughness will introduce reflectiveness to the material. For reflective materials like metals, you can use Roughness to create specular reflections which you can observe in the 3D view. Linked to the Normal and Height information, Roughness will warp reflections using these maps. If your surface is completely rough – there’s no need to include this map. Roughness becomes more interesting when you have a mix of roughness and smoothness in your material. For example, water leaking down a concrete wall would require the dry concrete to be completely rough, and the water to use a mixture of the two. For my concrete wall, I want a slight reflective quality to it. Thankfully, the default Roughness value provides a moderate degree of reflection, so we’ll leave this as it is. As with Normal and Height information, you can observe the final effect in the 3D View.
Creating Ambient Occlusion
Lastly, the light and shadow created in the game engine will be useful, but there is some information that the engine needs to render our material realistically. I like to include an Ambient Occlusion map to inform the game engine which parts of the material must be in shadow. For example, areas where the “height” and flatness should be at a sharp angle (like a brick receding into the concrete base) we should input some ambient occlusion to define these edges realistically. B2M will calculate these based on the Base-Colour and the Height/Normal information, so the question is usually how much ambient occlusion the material needs to be convincing. Using the 3D view, I will adjust the low/mid/high sliders to get the require effect (only very defined edges should need Ambient Occlusion, so I increase the lower tolerance so few of the soft edges the AO map includes.
With my five maps ready to go, I can export the material as five separate images. Before we do export, however, we need to ensure that we have the highest resolution image. By going back into the top menu, we need to turn the Output Size drop-down menu to select a higher-resolution image. For large textures (like grass and walls) which need to maintain their details as the player gets close to them, I recommend 4096 or 2048. Phone cameras these days are very high resolution, so it’s easy to get a high-resolution texture out of it. It’s worth mentioning that Unity will interpret this material at a maximum of 2048X2048, which is an unfortunate limitation of the software and I am not aware of this occurring in other engines. With an appropriate resolution selected, we can click “Export as bitmap” and choose where to save the material.
Make sure that you uncheck all the maps you don’t want (everything except Base-Colour, Normal, Height, Roughness, Ambient Occlusion) and ensure that you have an easy-to-find directory ready to export into.
When your materials are fully exported, they are now ready to be used in Substance Designer! Stay tuned for my next blog post, where I’ll go into detail on how we can add a moss material to this cement texture!