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