Blackhart Films
  • Home
  • Film Gallery
    • Short Films
    • Trailers / Promo Work
    • Demo Reels
    • Documentary/PSA's
    • Behind the Scenes
    • Tutorials
  • Art Gallery
    • 3D Models
  • Photography
  • Projects & Events
    • Survivors (Indie Film) >
      • Production Gallery
    • Conjurors of Composition >
      • Films
      • Production Gallery
      • Poet's Toolbox
    • St Johns River Art Fest (2016)
    • Chanukah 2015
    • Challah Bake 2016
    • Chanukah 2016
    • NEA Youth Activist Award
    • Hair Today Charity
  • Competitions
    • March 2017 Competition
  • About
  • Contact

BLOG

A Simple PBR Shader NodeGroup in Blender 3D

1/3/2016

8 Comments

 
Over the last few months I've been working to push my modelling and texturing skills. I've been practising on assorted projects in Blender 3D and Unity 5 (using Blender models). While searching for better tools to improve one of my weakest skills, texturing, I came across Allegorithmic's Substance Painter. It has quickly become an essential part of my workflow. I love the toolset; It's quick, it's well laid out, it has some robust generators and effects, and it feels familiar to anyone who has used Photoshop in the past. My biggest problem has been converting Substance Painter's PBR Metal/Roughness maps into materials within Blender's shader nodes. For every project I was basically creating a new node tree, playing with it until I got something that looked relatively pretty in Cycles, but was often inconsistent to what I was seeing in Substance Painter. This week, I finally made a single simple nodegroup which takes Substance Painter's PBR maps and turns them into Blender Shaders. All you have to do is append the nodegroup into your project, plug in your maps, and that's it! Let's take a look at its construction! 

What is the PBR Workflow?

The first step is of course to understand the PBR workflow, and what the maps from Substance Painter's Metal/Roughness output are used for. 

For a PBR Metal/Roughness workflow, there are 4 main maps that you are concerned about:
  1. Base Colour (Albedo, Diffuse, etc...)
    1. This is exactly as it sounds, this is the colour of your model. Anyone familiar with Blender will probably know this as the Diffuse map for the Diffuse BSDF shader.
  2. Roughness
    1. ​This material describes how "rough" the surface specularity is. It is a non-colour data map (black and white values), which is used to make a surface either perfectly smooth (not rough at all) and therefore perfectly shiny reflective (black values), or fully rough with very scattered reflections (white values). You should recognise this as the roughness inputs for the common Diffuse BSDF and Glossy BSDF shaders. 
  3. Metallic
    1. ​This is one of the less obvious material maps, but it basically describes how "metal" a material is. Metals interact with light differently than non-metals, so we have a non-colour data map which masks between the non-metal part of our shader group, and the metal part of our shader group. Our metals will reflect their colour from their material, and will have much more Fresnel reflectivity. 
  4. Normal (Bump, Displace, Height, etc...)
    1. ​This should also be familiar to anyone who has used Blender before, although you might know it as a "Bump Map". Specifically, though, this is a normal map because it is using the purple RGB output, and not a Bump or Height map using the non-colour data output. ​ This output adds surface details by faking displacement along the surface of the object. This allows you to add little details like pitting and scratches in the texture, rather than using far more vertices to actually model minute detail. 
For more information on Physically Based Rendering (PBR) and the science behind it, you can look at Allegorithmic's wonderful guides on the subject. From the perspective of an artist, though, all you really need to know is the above, and the implementation we're getting to below. 

How do we implement PBR in Blender?

NodeGroup
This NodeGroup is how!
In order to take advantage of PBR maps (in this case specifically Substance Painter's Metal/Roughness PBR maps), we must create a material node tree which implements the maps using the above concepts. Let's break down the node tree above and explain how it works.
InputsInputs
INPUTS
We have our 4 main input maps: our Base Colour, Roughness, Metallic, and Normal maps. We then also have value inputs for our Dielectric Reflectance, and our Normal Strength, which I will explain later.  These inputs will comprise all of our shaders, their masks, and their values. Very few inputs, very nice results. Simple and clean.
​

Non-Metal ShaderNon-Metal Shader
NON-METAL SHADER
The first section of our shader is the Non-Metal portion. This is the section which would be black on our metallic map, and would be the sections of the map for most items: papers, plastics, rubber, wood, etc... ​This section of the shader is composed of 4 main parts: A Diffuse BSDF node, a Glossy BSDF node, and a Mix Shader node, the mixing of which is controlled by a Layer Weight node. 

​
​Our Diffuse BSDF node (labelled in this example as "Base Colour") takes the Base Colour input for its 'color', and takes the Roughness input* for its 'roughness'. Then, we need the shiny parts of our non-metal shader, so we take a Glossy BSDF (labelled "Non-Metal Gloss"), and we give it our Roughness input (we leave this shader's 'color' as white). Finally, we're going to use a mix node to combine these shaders; Diffuse on the top input, Glossy on the bottom. However, we don't just want these to be 50-50 glossy and diffuse. We want this to be a dielectric setup, with slight gloss around the edges using the Fresnel algorithm to calculate the path of the light rays. For this, I use a Layer Weight node, and plug the 'Fresnel' output into the 'Factor' input of our Mix Shader. I give the 'Blend' value the input from our Shader "Dielectric Reflectance", this way I can change how strong the Fresnel effect is from outside the group, and per material. If you read the PBR guides above, you'd have found out that most non-metals sit around .04-.08; I set my node to default to .08 because I just happen to like shiny renders, though I do customise this value per object. 

And that's it! If you never planned to make a metallic object, you could technically stop there, add the normal map, and then you'd be done. But we're going to continue and add the metal shader as well, and mask between them. 

* You might notice that the roughness is being pushed first through a node labelled "Convert Roughness". The maps we get out of Substance Painter aren't as strong as we need for Blender, so we put the Roughness input through a math node first, to the power of 2, and then we can plug it in as needed. 
Metal ShaderMetal Shader
METAL SHADER​
Metals react differently to non-metals in the way that they reflect light and colour, so we handle them separately. You can, as always, learn more about this difference from the PBR guides above.  This section of the shader is made up simply of a Glossy BSDF node and a Mix Shader node, controlled by a new Layer Weight node.

Metals absorb certain frequencies of light and reflect the colour you observe them as, and are much shinier than non-metals, so our Glossy BSDF (labelled "Metallic Gloss") actually takes our Base Colour input for it's 'color', and again it takes our Roughness input for its 'roughness' (as above, run through the power of 2 conversion*). This goes into the bottom of our Mix Shader (labelled "Metallic Mix"), and our Non-Metal Shader output goes into the top. For our 'Factor' we are going to be taking another Layer Weight node with the 'Fresnel' output, but this time, the 'Blend' value is controlled by our Metallic map.

You could plug the Metallic map directly into the 'Blend' but I personally felt it wasn't strong enough, so I added another Math node (labelled "Increase Metallic") and told it to multiply the value of the input map by 2. By using a multiplication operation, you maintain your dielectric regions (0*2 = 0), while strengthening your metals. You're free to play with this value as you see fit for your projects. 

Normal MapNormal Map
NORMAL MAP
The final map​ we need to address is our normal map. This is by far the easiest to implement, because all we need to do is add the "Normal Map" node, give it our map for its 'color' input, and give it our Normal Strength for its 'strength' input. Then we can adjust the strength per material, and from outside the shader.**

** I will note that I've found Normal Strength values of .5-.75 work best. Using the full strength of 1.0 seems to be too much in Blender, it just ends up looking distorted and messy. Play with the strength in your own projects until you're comfortable with how it looks.
OutputsOutputs
OUTPUTS
We only need 2 outputs for this shader nodegroup: The shader itself, and the "displace" value which comes from the output of our normal map node. That's it!

We're done! We've created the shader! Now all that's left to do is test this out on a model we've painted using Substance Painter...

Testing the PBR Shader NodeGroup!

Nodes In Use
Plugging in our maps!
Now that we've finished our shader nodegroup, let's plug in our maps, and see how this looks...
Download Test Scene
If you like this set up, you can download the test scene from above. It includes my Space Hauler model, its texture maps from Substance Painter, the environment texture I used for the reflections in the previews***, and of course the shader nodegroup.
I'm quite pleased with the results myself. I've tried this on a number of models, and I plan to append this nodegroup into all my projects from now on. Once I get my maps out of Substance Painter, this shader set up means I can simply plug my maps in and focus my time in Blender more on the composition of the scene, rather than fiddling with shader nodes time and again with different innaccurate results every time. I like having an elegant and fast solution like this which covers basically every use case, with the exception of course for more niche materials like emissive or transparent objects.​

If you use my nodegroup in your works, please leave me some credit (even something as simple as "Shader by @BlackhartFilms" in the description text).


I hope this overview has been useful, and I look forward to seeing how people use this technique! Happy Blending!

Creative Commons License
Blender PBR Shader by Jeffrey Hepburn is licensed under a Creative Commons Attribution 4.0 International License.

*** HDRI Environment Maps by Greg Zaal
Share
8 Comments
Mike
3/12/2016 08:43:23 am

Hello,
thanks for that shader. I searched a long time for something like that. Do you testet this with the output-maps from Substance Designer too? Or must i go from Designer into Painter and then to Blender?

Reply
Blackhart
3/12/2016 11:07:16 am

Yes, if you're using PBR metal/rough outputs from Substance Designer, they are PBR maps, you can save them out of Substance Designer. I use Designer for most of my large environmental objects such as ground textures, walls, floors, etc...

Reply
Mike
3/12/2016 09:17:06 am

Hello again,

now i tested your shader itself and i have problems with the normal_map. there is no "bump" effect. the objekt looks flat. i only testet a brickshader from substance painter. nothing complicatet. but the brick-edges are flat. anyway what kind of normal strengh i choose.

Reply
Blackhart
3/12/2016 11:09:29 am

Have you made sure that in the node-group the normal map node takes the normal map from the input, and plugs into the displace for the output? And that outside this nodegroup that your displace output connects to the displacement input on the shader out?

Reply
Mike
3/12/2016 11:30:50 am

Thats was the mistake. Now i have a bump-effect, but at some sides of the cube it seems, the normal is inverted. I have here three screenshots in the dropboxfolder. on picture "correct" it looks good, at the other pictures you see the "reverse" side of the cube and a comparison. why is this?

https://www.dropbox.com/sh/xm1fhoa1clkdw18/AAAJJi0NHbvVq6MJDg_3rKJwa?dl=0

Paulodgn
4/20/2016 07:28:51 pm

Thank you so much for this its works great. Ive been trying to this for a couple of weeks with not very good results. Great job!

Reply
eknightGER
5/14/2016 09:41:40 am

Thank you for this - I just read Allegorithmics PBR guide and basically came up with the same shader group (although I am playing with the height maps in addition to the normal maps, I see where that goes :-). But seeing you play with the strengh of the maps input (eg. power 2 and multiply 2) is a very good idea, that could solve my issues of the effect's strength. One idea on the dielectric could be to assign different PBR materials to the object in Blender that plays with the fresnel value driven by a texture map or vertices based material assignment.

Great work, keep it up!

Reply
eknightGER
5/22/2016 05:26:22 am

I have played with the node set-up a bit as I found that using normal map input into displacement gave me a number of small micro-artifacts on the painted surface. So I tried using the exported height map from Substance painter instead and put it into a bump node and that into the normal inputs of all the shaders. I found that this delivered an improved result for me. Probably something worth exploring further.

Reply

Your comment will be posted after it is approved.


Leave a Reply.

    Author

    My name is Jeffrey Hepburn, and I'm a young writer, graphic design artist, and aspiring filmmaker.

    View my profile on LinkedIn

    Categories

    All
    Artistic Thoughts
    Game Development
    News & Events
    Poems
    Political Thoughts
    Programming
    Technology
    YouTube Videos



    Archives

    June 2016
    January 2016
    November 2015
    September 2015
    August 2015
    July 2015
    June 2015
    May 2015
    April 2015
    March 2015
    February 2015
    January 2015
    December 2014
    November 2014
    October 2014
    September 2014
    August 2014
    July 2014
    March 2014
    February 2014
    January 2014

    RSS Feed


    Tweets by @BlackhartFilms
Picture
© COPYRIGHT 2017. ALL RIGHTS RESERVED.
  • Home
  • Film Gallery
    • Short Films
    • Trailers / Promo Work
    • Demo Reels
    • Documentary/PSA's
    • Behind the Scenes
    • Tutorials
  • Art Gallery
    • 3D Models
  • Photography
  • Projects & Events
    • Survivors (Indie Film) >
      • Production Gallery
    • Conjurors of Composition >
      • Films
      • Production Gallery
      • Poet's Toolbox
    • St Johns River Art Fest (2016)
    • Chanukah 2015
    • Challah Bake 2016
    • Chanukah 2016
    • NEA Youth Activist Award
    • Hair Today Charity
  • Competitions
    • March 2017 Competition
  • About
  • Contact
✕