Substance and Blender 2.79+

In Blender 2.79, there is a new Principled BSDF shader. This means there’s a new workflow for importing textures from Substance Painter and Substance Designer. The good news is the workflow is very simple. But it’s a new workflow nonetheless.

To loads PBR textures for the Principled BSDF, you’ll need the following channels:

  • Base Color
  • Roughness
  • Metallic
  • Normals (formatted for OpenGL)

You might notice this is the default format for Substance. So if you like, you can just use the “Document Channels” export mode in Substance Painter. Alternately, you can use this Substance Painter export preset. You can add it to your shelf, or see here for creating and installing export presets. Download it here: https://drive.google.com/file/d/0B4md98mV7RHJMGZfZXBuSEx0dU0/view?usp=sharing

The textures are simply loaded and connected to their corresponding sockets. Note that normal, roughness, and metallic must be set to “non color data” to disable gamma correction.

pbr_easy

Other Map Types

Emission

To use emission maps, connect them to an emission node and combine with with the Principled BSDF via an Add Shader:

Transmission (in the sense of “glass”)

The Principled BSDF supports dielectric transmission, so you can hook up your transmission/opacity map directly. Note that the metallic map will “override” transmission, since transmission only applies to the dielectric layer. This makes sense when you think about it for a second, since glass is also a dielectric, and metals aren’t transparent. In a lot of softwares’ ubershaders, however, transmission overrides everything so this might be jarring at first.

Transmission (in the sense of “alpha maps”)

You can use alpha maps by mixing the Principled BSDF with a Transparent BSDF. In this example, our basecolor texture has cutout opacity data stored in the alpha channel:

Ambient Occlusion

You don’t need AO maps in Cycles, ever. Ambient Occlusion is shadows (aka occlusion) for the global “ambient” lamp. Hence the name. Cycles does not have an ambient lamp object. The world light is a physical light at infinity in all directions, rather than an ambient light that adds an even glow to things. There is a “World AO” options, which is technically an ambient lamp with built-in occlusion calculation. There is no option to use pre-baked AO with the World AO function, however. AO maps should never be applied to diffuse or direct lighting, only to the ambient lamp. See this famous blog post for more information: http://mentalraytips.blogspot.com/2008/11/joy-of-little-ambience.html

While AO maps applied to diffuse can be very useful for dirt effects, it is almost always preferable to pre-mix this into the regular basecolor/rough/normal/metal textures, rather than loading baked AO separately and compositing it within the shader. Adding AO dirt during texture painting will allow you to avoid loading the AO map, saving memory. It also allows you to “bake” the compositing operation, as well as having more control over said compositing.

Height/Displacement

Microdisplacement can be used to represent heightmaps with tessellation/displacement. This workflow has not changed since Blender 2.78, and is the same whether you’re using the Principled BSDF or the legacy PBR node groups.

Advertisements

Principled BSDF – Cycles gets a native PBR shader

chair_pbrdf_high_q

(The spaceship chairs from Homeward, updated with the new shader)

If you open a build of what will become Blender 2.79 and create a material, you’ll find yourself face to face with a giant, unfamiliar node. Although if you’ve used the Renderman plugin, or worked in apps like Houdini or Unreal, you might recognize this node after a second. It’s an implementation of Disney’s Principled BSDF, and it’s Cycles’ new physical uber shader. The principled shader has become something of a de facto standard “PBR” shader. It’s the viewport shader in Substance Painter/Designer, and it is used in a number of other tools as well.

This means we’re done with PBR hack node groups. No more simple_pbr_v5 (which was your favorite PBR hack group, rite?), no more fresnel node setups. No more appending nodes every project. It’s over, you’re free. It’s all one built in node now, and it works just like the shaders in, say, Unreal. Or Substance. Or Renderman. Or Mantra.

First of all, some background on the Principled Shader: https://disney-animation.s3.amazonaws.com/library/s2012_pbs_disney_brdf_notes_v2.pdf

If you’re just looking in that paper for what the parameters are, skip over the mumbo jumbo down to section 5.2. It even includes helpful example renders.

 

So how do you hook up base color, roughness, metallic, and normal maps to this shader? Like this:

pbr_easy

Normal map needs to be passed through the normal map node still, and remember that roughness, metallic, and normal maps are “non color data”, not managed “color” textures!

As another benefit, the principled shader is also implemented in OpenGL! Cycles material draw mode does not use scene lights, so you still have solid lights. But the result is far more accurate than our old node groups:

 

And now, answers to questions that are likely to come up:

Does this work on GPUs?

Yes, both CUDA and OpenCL.

 

Do I need to square roughness?/Roughness does not match the Glossy BSDF

The Principled BSDF squares roughness internally. This is generally easier to control, and allows better compatibility with other software. If you need to match a value you had on the glossy bsdf, just type in <value> ^ 0.5, Blender will calculate the equivalent.

 

Do I still need to account for roughness in fresnel?

Nope. Roughness is correctly handled within the shader. Just plug in your roughness map and go.

 

I see there’s a specular input. Do I need to export a specular map from Substance?

No! The specular slider is mainly there to tweak reflection brightness. Generally, you can leave that as 0.5 to start and adjust up or down if you need weaker or stronger reflections. If you want to match Substance, leave it at 0.5 (that’s what Substance’s viewport does).

It actually corresponds to IOR where 0-1 is equivalent to an IOR range of 1.0-1.8. The default is 0.5, which corresponds to an IOR of 1.5. (for reference, in the typical PBR Specular workflow IOR=1.5 corresponds to a specular value of 0.04).

 

Some other apps allows emission or tinted refraction in the principled shader. Is this not supported in Cycles?

Cycles already has easy and fast ways to do these that still work with the principled shader, so they’re not integrated. For emission, simply combine the Principled Shader node with an Emission Shader node using the Add Shader. For tinted refraction, add a volume absorption node to the volume output.

 

What are the limitations of the shader in material draw view (OpenGL) compared to the full render in Cycles?

  • Anisotropy does not respect custom tangents
  • Refraction is not supported
  • SSS is a very limited approximation
  • Only solid mode lighting, aka Blender’s “OpenGL Lights” are supported. This is a general limitation of Cycles material draw view

 

Simple PBR v5

UPDATE

You should use the Principled BSDF shader instead of PBR node groups such as Simple PBR. See https://jtheninja.wordpress.com/2017/05/11/substance-and-blender-2-79/ for more information.


It’s been awhile since I posted a new version of Simple PBR. It’s gone through a couple internal updates (one of which I brought back to v4 because I found it useful). If you want to some techno-rambling about what exactly is changed, I’ll describe it at the end of the post. A lot of you probably just want the shader and some basic instructions, so, here you go:

overview

Download it here: https://drive.google.com/open?id=0B4md98mV7RHJaGFKcVpmVjRvZ0U

There are two main nodes inside, “Simple PBR v5” and “Simple fastPBR v5”. Both give mostly similar results and have the same inputs. fastPBR is slightly faster to render. Not by much, you might not even notice the difference on big scenes, but Simple fastPBR skips a few things to optimize the shader a bit. In exchange for making you wait slightly longer, the regular version will give slightly more realistic results with higher roughness.

IMPORTANT: SIMPLE PBR v5 REQUIRES BLENDER 2.78+!!!! It is NOT compatible with 2.77a!


“Wait!! There used to be a Substance and Substance Painter shader, what do I do now?!”

Simple PBR v5 has transcended such things. You can now just use the regular Simple PBR or Simple fastPBR with Substance. An updated Blender Cycles export preset for Substance Painter is included. If you were using the one that came with Simple PBR v4, you should replace it with the new one. It will export maps for each of the 4 channels. Roughness, metallic, and normalOpenGL should be loaded as “non-color data”, base color should be loaded as the default “color”. You will need to add a normal map node in-between the normal input on the shader and your normalOpenGL image node. See below for the example setup.

Note that now all Simple PBR shaders use squared roughness. This is different from the raw glossy BSDF, but it’s easier to work with and it seems the way all the other community PBR shaders are going.


“How do I use Simple PBR?”

Glad you asked. Append it to your scene and plug it into the material output. Typically your textures go something like this:

example

The only other thing worth noting is that if you are not using a bump or normal map, you will need to manually supply the mesh normal with the geometry node as in the screenshot above (it’s set up in the source file too for your reference). This is due to some limitations with Cycles and node groups not initializing the shader normal properly in some cases, using the geometry > normal output just sets it manually to the correct value.


Simple glazePBR and Simple PBR Glass

Simple glazePBR is just the dielectric reflection component of Simple PBR. You can use it to add a realistic gloss to non-conductive objects that are not diffuse. Like, say, skin. Or you can make some sweet (and easy!) carpaint but sticking it after the regular Simple PBR.

Simple PBR Glass is, well, a glass shader. It was sort of a last-minute addition to the kit. It hit me that I often use a bunch of the same nodes when making glass shaders, which was the same impetus that created Simple PBR in the first place. So meet the refractive member of the family! It has built-in volumetric colors (absorption only! no performance worries here, I checked carefully!). It also will automatically switch to transparent shadows instead of caustics when roughness is set to 0, since Cycles can’t reliably produce caustics from sharp refractions. The “color density” input will adjust the strength of the absorption effect


Did you know that Cycles it getting support for Disney’s “principled BRDF”? It’s true: https://blenderartists.org/forum/showthread.php?403342-Cycles-Disney-Brdf
Once this is done it will more or less render obsolete all these community PBR shaders. There may still be a need for the glass and glaze shaders, it’s something I’ll look into when the time comes.


Finally, if you find Simple PBR useful, I’d appreciate if you could throw some coins in the tip jar in the sidebar



TECHNICAL MUMBO JUMBO SECTION

Ok, so what is actually new in v5? Here’s the important bits, I’ll explain why for each one:

  • Plain “Simple PBR v5” uses the new Multiscatter GGX glossy option in 2.78. This gives brighter, more correct results with high roughness. It comes with a bit of a noise and speed cost, hence the impetus for fastPBR, which uses the old simple GGX.
  • Diffuse roughness is now calculated as glossy roughness * 0.33 instead of using the glossy roughness directly. After actually reading some docs on Oren-Nayer shaders (how useful) I found that most real-world surfaces will not exhibit sigma values beyond 0.5, with most topping out around 0.3. This is something I probably should’ve remembered from my LuxBlend days… Anyway, I thought for awhile on the best way to handle diffuse roughness in Simple PBR. Using glossy roughness directly led to weird velvety-looks with roughness=1. I thought about disconnecting it, or locking it at a value, or exposing it as its own parameter. After awhile, I decided on using the glossy roughness * 0.33. It’s kind of arbitrary, but it gives a decent result in most cases without having to manually set it.
  • Simple fastPBR does not use Oren-Nayer at all, diffuse roughness is disconnected interally and set to 0. This gives a small speedup at the cost of realism on rough surfaces.
  • Roughness is squared in all cases. Most of the community PBR shaders, particularly Andrew Price’s, do this as it’s easier to work with and allows compatibility with most PBR authoring tools. This does mean it gives different results than a bare glossy BSDF, but I think most people will figure it out. Additionally, the roughness squaring is done as roughness*roughness, rather than roughness^2, just to be safe. This does not make a speed difference that I’ve ever observed, but why do things the potentially slower way?
  • Substance Painter export no longer packs roughness/metallic/height to an RGB texture. In 2.78, Cycles adds native support for single-channel textures (grayscale, float, scalar, single, whatever you want to call them). By exporting roughness and metallic into seperate grayscale files, they can be loaded using one channel each, meaning a total of 10 texture channels are loaded. Basecolor and normal both require 4, as Cycles does not have an RGB texture type, just RGBA. The old packed method required initializing a 3rd RGBA texture meaning 12 channels total. So the new method saves you 16.7% texture memory at the cost of making you load a 4th image node. (I recommend the “multiple images” option on the node wrangler addon, btw). Previously, seperate textures would’ve result in their own RGBA textures internally resulting in 16 channels, hence the intial design of the packed version. This is no longer needed.
  • You shouldn’t need to manually disable heterogeneous volumes or transparent shadows with the glass shader. I tested carefully to make sure these weren’t getting kicked on when they weren’t supposed to, and there is no render time difference that I can pick up.

Simple PBR v4

UPDATE

You should use the Principled BSDF shader instead of PBR node groups such as Simple PBR. See https://jtheninja.wordpress.com/2017/05/11/substance-and-blender-2-79/ for more information.


Oops, I kept forgetting to post this. Awhile back, I made a note on the old Simple PBR that it had some mistakes in it, and this video by CynicatPro showed a better shader: https://youtu.be/pNiVB7tRG68

I also mentioned I had modified Simple PBR to take these things into account. At some point I mentioned I was going to post it, but kept forgetting to, Well, some people kept commenting to remind me, so, while I watch Bob Ross on Twitch, I’ve packed it up.

Say hello to Simple PBR v4 (no, I never posted v3, it was short lived).

~~~~UPDATE July 18 2016: I’ve modified the roughness calculation for diffuse slightly. This should give less wacky results. Same download link as before ~~~~

https://dl.dropboxusercontent.com/u/1706676/YouTube%20Summary%20Files/simple_pbr_v4.zip

Inside there you’ll find 4 node groups:

Simple PBR v4 – Simple PBR, which is sadly becoming a bit less simple internally, but it remains a simple metal/rough shader on the outside. This is the main shader, everything else is modifications of Simple PBR. It should work for metal and opaque dielectric surfaces.

Substance PBR v4 – Simple PBR v4, but with the roughness squared. This will make it play nice with roughness maps generated by Allegorithmic’s substance toolkit.

PBR Fresnel – a group of just the fresnel mask part. This is essentially the same as the group CynicatPro makes in his YouTube video. But it’s there if you need it (such as adding gloss to skin).

Substance Painter PBR v4 – name is a mouthful. Anyway, it’s Substance PBR v4, but with even more mods. It has a channel split and the normal map node integrated directly. It’s designed to be used with a Substance Painter export preset that is included in the bundle. That would be the “Blender Cycles.spexp” file. To install the preset, toss it in your Substance Painter shelf folder. See this doc on where to find that: https://support.allegorithmic.com/documentation/display/SPDOC/Creating+export+presets

Note that these groups will not behave properly with the normal input disconnected. If you are not using a bump or normal map, feed in the default normal from the texture coordinate or geometry nodes (either works).

_____

If you are not using Allegorithmic’s Substance tools, you can stop reading now. The rest of the post deals with integrating these shaders with the Substance twins.

The Substance Painter preset will generate 3 maps:

basecolor (nothing weird here)

“metalRough” – includes roughness in the red channel, and metalness in the green channel. The blue channel is blank.

normalOpenGL – Painter’s OpenGL Normal converted map. This map compiles your height and normal channels together with your baked normal map to create a single final normal map.

You will find corresponding inputs for each of these 3 maps on the Substance Painter PBR v4 node group. Just plug them in, and change the normalOpenGL and metalRough to non-color data (this is important, they will not work correctly as “color”). Don’t worry about adding a normal map node or splitting metalRough’s red and green channels, the node has all of that built in, then passes it to Simple PBR. Just import your textures, set non-color data on metalRough and normalOpenGL, attach them to the group, hook the group to your mat output. Nothing else to it!

Screenshot 2015-10-30 22.21.59

Remember that Substance Painter exports PNG files as 16bit, which Cycles will import as float textures. These use more memory, and if you’re rendering on an Nvidia card, you can only have 5 in your scene. Rendering on AMD? Well, you get zero. This has nothing to do with the Simple PBR shaders, just something you should be aware of. You can use a format that is 8bit in Painter, like Targa. Or just live with it.

Cycles scene optimizations: Ray visibility

If you want to make something invisible to a certain ray type in Blender/Cycles, most people do things like this:

Screen Shot 2015-02-21 at 7.24.15 PM

STOP DOING THAT.

You are making Cycles waste time doing worthless calculations. Instead, go over to the object tab, and use these instead:

Screen Shot 2015-02-21 at 7.27.14 PM

Unchecking “camera” there will produce the exact same result (the object is invisible when viewed directly, but otherwise appears normally), but it goes about it differently. The shader node setup tells Cycles when evaluating the material, figure out the current ray type, and if it’s camera, choose the second input on the mix shader. This is a transparent BSDF node at full white, so the ray passes unchanged.

Ray vis does it a much more efficient way: it just tells Cycles “if the current ray is a camera ray, don’t even bother checking if you hit this object, just assume you didn’t”. This is important, as it allows us to filter out the object while doing intersection tests (render nerd speak for “checking to see what the ray hit”). Even better, it allows us to avoid running the shader at all, much less realizing the result was a transparent BSDF and having to continue the path and do the whole thing over on the next object we hit.

It gets worse though. The light path shader includes a transparent BSDF, thus, it enables transparent shadows. Realtime engines and rasterizers have taught too many people to think alpha maps are their friends. But raytracers are different: to them alpha maps are evil, because they create a horrible effect called transparent shadows. Raytrace shadows are computed by tracing a path from the shading point (that’s where the initial ray landed) out to a lamp, and seeing if anything blocks the path. If something is there, the object is “in shadow” and the lamp contributes nothing. If it has a clear shot, it is not in shadow, and the lamp contributes at full strength. Simple.

Transparent shadows crap all over that simplicity. They cause the shadow ray test to return bullshit like “the ray might be blocked, or maybe it isn’t”. The only way to find out is to to run the shader (which we didn’t even have to do in the first place for opaque shadows!) and figure out what the actual opacity is at the point on the object we hit, then trace another ray from this point to see if we were actually blocked entirely by something else and we did all this for nothing (lolz). God help you if that “something else” is also transparent, then we have to do this shit all over again.

Needless to say, that wastes a lot of time. And now you know why that “transparent shadows” box is in the material options. Unchecking that tells Cycles “I know this mat has a transparent BSDF, but just ignore that and do opaque shadows anyway”. Because that can save a lot of time if no one is going to notice an object is casting solid shadows.

Now, sometimes we don’t have a choice, (alpha maps have their uses), but in the case of 100% transparency to a particular ray type, we do. We can just turn off ray visibility for that type, and have a simple shader with no transparency.

Just to compare, I set up this scene. The cube is invisible to camera rays:

Screen Shot 2015-02-21 at 7.42.18 PM

Regardless of if we use ray visibility or the light-path shader, the result is the same. But the render times aren’t:

  • Diffuse-only shader, camera ray visibility disabled: 1.73sec
  • Diffuse/transparent mix by “is camera ray”, camera ray visibility enabled: 2.28sec
  • Diffuse/transparent mix by “is camera ray”, camera ray visibility enabled, but “transparent shadows” disabled: 2.10sec

This is obviously a worst-case scenario, but you can see the impact of the extra calculations. 30% longer to render the exact same image! Using the same setup with transparent shadows disabled (still the same result, because light path “is camera ray” will never evaluate to 1 for a shadow ray) is only 2.1 sec. That’s means about 35% of that penalty wasn’t even due to our extra shader stuff, it was due to the useless enabling of transparent shadows.

So there we have it. Ray visibility is your friend.

_______

“But wait!” you might be saying, “I need to do some ray-switching for a bunch of objects with this one material! Light path is a lot easier in this case!”

Python to the rescue. This will disable camera visibility on all selected objects (select one object, then use “select > linked > material” to grab all objects with your mat):

import bpy

for obj in bpy.context.selected_objects:
    bpy.context.scene.objects.active = obj
    bpy.context.object.cycles_visibility.camera = False

If you need to flip a different ray visibility switch, you can just change that last line. This version will turn on transmission visibility:

import bpy

for obj in bpy.context.selected_objects:
    bpy.context.scene.objects.active = obj
    bpy.context.object.cycles_visibility.transmission = True

The python names for the 6 switches are:

camera
diffuse
glossy
transmission
scatter
shadow

Cycles – lamp cover optimizations

Does your scene have a light source with a glass cover on it? Headlights, flashlight, lantern, etc? Here’s a little tip for the glass. Use this shader instead of the glass bsdf or a refraction/glossy mix:

Image

 

This way, the “glass” is considered transparent instead of transmissive. This gives a few nice benefits:

  • The light is not considered a “caustic” and will shine even with no-caustics enabled, and be MUCH easier to sample if you are lighting with it directly (instead of an invisible lamp outside the fixture)
  • The light source is considered direct, meaning it is affected by the “clamp direct” value instead of the harsh, firefly-stomping “clamp indirect” setting
  • Being direct light also means it will appear in the “emit” pass instead of the transmission passes, which makes adding glow effects and adjusting lamp power a lot easier.

There’s also another even further optimization you can do. This shader, containing the transparent bsdf, casts transparent shadows. Transparent shadows are bad, they make sampling lamps slower (Cycles has to call the shader, then trace another ray the rest of the distance instead of simply seeing if it hit something or not). While it won’t usually have a big affect on some small panes of glass, you can squeeze out a little extra speed by disabling shadow-casting entirely for your glass object in the ray visibility panel:Image