Material Basics: PBR Model

Theory

Popular in modern 3d rendering and games, physically based rendering shading model that attempts to mimic real life materials in a more direct manner than the older specular model of shading.

There are some great articles on the web where you can learn more about the model in detail, but in brief, a basic PBR shader simulates three things:

  • Materials have some degree of roughness/smoothness, and reflect light in either diffuse or specular manners depending on this
  • Some materials are metallic, and reflect light in a different manner because of this
  • Conservation of energy is preserved between incoming light and outgoing light, so the intensity of reflection will vary depending on which type of reflection is more prominent
Spheres rendered in Blender (Eevee)

Above you can see some spheres rendered in Blender with different levels of roughness, and as both metallic and dielectric (non-metallic) surface. The two primary differences of metallic surfaces are that

  • Metallic surfaces reflect specular light more effectively. Because of the conservation of energy, glossy metallic surfaces must reflect less diffuse light, and appear darker as a result
  • Reflections on metallic surfaces are tinted to the colour of the surface, whereas in dielectric materials the reflections match the colour of the object they represent

Nolimits 2 caveats

The PBR implementation in Nolimits 2 isn’t accurate for metallic surfaces, as it does not correctly represent the conservation of energy as seen in the Blender render above. As the metallic surface becomes more glossy in Nolimits, it does not become darker, and as a result many metallic materials will appear too “shiny” in Nolimits.

The same spheres as rendered in NL2

In addition, metallic surfaces placed in tunnels or dark areas would reflect the skybox so you might want to use a custom reflection cubemap in these areas, However custom cubemaps are not blurred like the default skybox is, causing those materials to appear too glossy.

Just be aware that some materials may look strange as a result of these innacuracies, and that you may need to manually adjust your materials as a result. Two workarounds I often user are to:

  • Reduce the metallic register to a fractional value e.g. Metallic = 0.5;. This isn’t usually done, as half-metallic materials aren’t really a thing, but in Nolimits this may improve the look of certain materials
  • Rather than using custom cubemaps, I increase roughness in areas with a dark ambient colour. This again isn’t physically correct for the material, but will remove the reflection on objects.
  • If you don’t require reflections at all, disable them outright in the reflections tab

Material setup

Most textured PBR materials will benefit from dedicated metallic and roughness textures, allowing the PBR properties of the material to vary across the texture. I used this texture from Textures.com as it demonstrates both metallic and dielectric details. You can download this texture and follow along, you just need a free account on the site. You’ll want to download the albedo, normal, metallic and roughness maps, and you’ll need to convert the TIFF files that are downloaded into a format Nolimits accepts, such as JPEG.

Multple PBR maps are sampled to create a surface with per-pixel PBR properties

Create a new NL2MAT assign the diffuse, metallic, roughness and normal map to seperate texture units. (I used Tex0-Tex3 in the order listed)

To enable PBR, you’ll need to write a bit of custom NL2MAT shader code. The programmable shader core can seem daunting at first, but it is functionally just a fancy colour mixer, we’ll just be using it to assign our texture maps to their PBR functions, otherwise NL2 has no idea what to do with them. The shader code we will use is:

Result = Tex0;
Metallic = Tex1;
Roughness = Tex2;
  • Result is the diffuse component of our material, so we assign the texture file in Texture unit 0 as the diffuse map.
  • We assign Texture unit 1 as Metallic
  • We assign Texture unit 2 as Roughness
  • Normal maps fall outside the scope of the shader core, so we don’t need to write any code for Texture unit 3.

For most PBR materials, you’ll want to enable cubemap reflections, so check faked reflections under the reflections tab. Also check Affected by bumps to improve the look of normal mapped materials. The rest of the settings do not affect PBR materials.

Spheres in NL2 without PBR (left) and with PBR (right)

Checklist

When creating PBR materials, you need the following for PBR to work

  • You need to assign a metallic value (e.g. =0, =1, or a texture unit)
  • You need to assign either a Roughness value or a Smoothness value
  • You cannot use the Specular register, it will produce an error when used in combination with PBR registers
  • You should enable reflections for most PBR materials

Material Basics: Specular Model

Material Setup

Let’s start by creating a basic material using some pre-made textures, and then see what we can do to improve the result. For a lot of materials, we can get away with just using a Diffuse(or albedo) map and a Normal map. I used this texture from Textures.com, which you can also download after making a free account on the site. You’ll want to download the Albedo and Normal map, and you’ll need to convert the TIFF files that are downloaded into a format NL2 accepts, such as JPEG .

Create a new NL2mat, set the shading mode in the RGB Color tab to Bump Lighting, then go to textures and assign your diffuse map to Texture Unit 0, and your normal map to Texture Unit 1, being sure to enable Bump Mode (using normal map) for your normal map texture. Apply that material to the NL2SCO of your choice, and when you reload the object you’ll get something that looks like this:

Rock material with textures assigned

For some textures, the result after doing that might look alright, and you might be tempted to save and use the material as-is. But in the case of our rock texture, something clearly doesn’t look quite right. We’ve got good quality diffuse and normal maps, but we haven’t yet authored the third important part of our material, the specularity.

Theory

Specular shading mimics the two ways light bounces off of objects in the real world. All objects reflect light in two ways; the first is diffuse reflection, where light hits a surface and are scattered in all directions randomly. Some of these light rays eventually bounce into our eyes, and that is how we perceive an object as having a certain colour, or albedo. The second way light interacts with objects is through specular reflection, where light bounces off a surface in a largely uniform direction, at an angle of reflectance from the surface.

Direction of light bounces for diffuse and specular reflection

All surfaces reflect light in both diffuse and specular manners, but the ratio will change depending on the surface properties. A matte/diffuse surface will reflect most light diffusely, whereas a shiny surface will reflect more light in a specular fashion.

Phong shading like that used in NL2 includes an approximation of this effect, it is performed on every pixel on the materials surface, and at certain angles will cause the specular dot. Its formula for the specularity, if you are interested, is sinn(θ), where Theta is the angle of light hitting the object, and n is the glossiness value you’ve probably seen in the NL2MAT editor. Take a look at the graph for that formula:

Just imagine the height of the line to be the brightness of the specular dot, and you start to see how the formula can be used to form the shape of the dot on sreen. full white in the centre and the curved edges cause the light to smoothly drop off around it.

Glossiness values

So, we now know the glossiness slider in the NL2mat editor affects the size of that odd-looking white dot, we’ll take a look at how that changes as we adjust its value. Even without any textures, just changing the glossiness allows us to invoke the idea of different real-life surfaces. In this example, a high value might be reminiscent of a Malteser chocolate, and a low value might be reminiscent of a ball made of velvet.

Identical materials, but the glossiness value is being increased from left to right

Let’s now go back to our rock material from before, and apply the theory above to this material. This is intended to be a rough, dry rock texture; it’s surface isn’t polished or shiny in any way, so let’s start by reducing the glossiness to a low value. I enabled Override Glossiness in the Basic tab, and set a low value (5%). I also lowered the specular colour to 50% grey. You’ll often want to change the specular colour in this way, as matte surfaces tend to reflect less light overall.

Rock material with adjusted specular values

That looks much better. Specular highlighting is still visible, but is much less harsh and without pixels that have been blown out to white.

As one final experiment, we’ll change the rock to look like it’s been out in the rain. It’s going to gain glossiness as a result: I chose a value of 90%, which would be suitable for a rock that had been quite thoroughly rained upon. I upped the specular colour slightly to 70% grey, which is more noticable but does not get blown out. As an extra trick to sell the effect, I also darkened the diffuse colour a little by setting the override color to 80% grey. This might not be necessary if your entire scene is wet, but if you have a dry and a wet version of an object near to each other, it will make the transition more believable.

Rock material adjusted to appear wet

Concluding points

hopefully, that’s given you some things to consider when making your materials, and some new insight on how the shading model actually works. Some concluding hints to refer to when making your materials would be:

  • Take a look at real photographic reference for the material you’re creating. Take note of how light reflects from the surface, identify whether you can see specular or diffuse reflections, and to what degree with each.
  • Think about the variations the physical material you’re mimicking can take. For example, don’t say “This is rock”, but “This is well eroded and smooth rock, but not polished”.
  • Set your shininess value to the right value before touching the specular colour, this will result in a more realistic result.