Importing Substance Painter texture to Cycles

UPDATE (May 2017)

You should use the Principled BSDF shader instead of the method described here. See for more information.


Substance Painter is a powerful physically-based (PBR) texturing tool. It’s primarily aimed at game use (for now…), but you can easily make use of its output in Cycles. In this tutorial, I’m going to show you how to do that.

To start, I’ve given everyone’s favorite monkey an interesting paint job using the default color, height, roughness, and metallic channels.


First order of business is to export these for Blender. Hit File > Export, and just use the default “Document Channels + Normal” preset.

export channels

Now let’s look at our shader in Cycles. We’ll start by making the simplest, most standard physical shader, a diffuse/glossy mix with fresnel.

starting nodes

NOTE: Some people like to use the layer weight node instead of the fresnel node. If that’s you, go right ahead. I’m just using the fresnel node here for simplicity.

Base Color

Our first channel to deal with is base color. There’s not much to this one. We have a base color image, we’ll just load it and plug it into the diffuse BSDF’s color slot.

base color attatched


Our next texture if the roughness map. As you might have guessed, we’re connecting it to the roughness inputs on both the diffuse and glossy nodes. However, there’s a couple things we need to set to make sure Cycles interprets the map correctly. The first is to change the node from “color” to “non-color data” (as that is what the roughness map is). Any channel that is not set as “sRGB” in substance painter should be loaded as non-color data. Here we see that base color is sRGB (and thus should be loaded as color), but the rest of our channels are luminance (marked with an “L”), so they should be loaded as non-color data.

sp channel type

The other thing we need to do is square the roughness value to match the range between SP and Cycles. To do that, add a math node, set it to “power”, connect your roughness map to the top slot, and set the bottom slot to “2.0”.

rough attached

Let’s check how it looks so far:


Ok, it’s a start. The colors are right at least. Now let’s deal with that height channel. There’s a few different ways to do that:

Height Method 1: Bump Node

One obvious way to handle the height channel is to do what SP shows it as: load the height texture and stick it in as a bump map. To do that, we’ll pass it through the bump node and attach that to our normal inputs

bump node

This works ok, but you often need to fine-tune the bump strength, and if you have a normal map for your object, we have to add more spaghetti (and load another texture) to integrate the two. There’s a better way, namely…

Height Method 2: The Normal OpenGL output

Substance Painter can generate a number of “converted” texture maps. One of which is the “Normal OpenGL” channel, which generates an OpenGL-style tangent-space normal map using the height channel and the object’s normal map (if it has one). We can attached it with the normal map node, like usual.

normal ogl node

Let’s try that:


Perfect! Works right out of the box! In this case, our object didn’t have a baked normal map in Substance Painter. But in case it did (such as baked sculpting detail) the normal map will contain that as well as your height painting, so you don’t need to do anything else to connect the two.

Optional Height Method 3: The Displacement Output (Which Doesn’t Work Right)

There’s one more method you can do. It doesn’t really behave the way it should since it relies on an unfinished feature in Cycles, but you can instead attach the height map to the displacement output. If you don’t turn on experimental features, this has basically the same result as the bump node method. However, if you enable experimental and change the displace mode to “both” (aka, auto-bump), Cycles will displace the vertices of the mesh as best it can to fit the height map, then adjust the normals to fit the rest of the way.

It’s kind of cool, but again, this is an UNFINISHED FEATURE of Cycles that DOES NOT WORK QUITE RIGHT. (don’t enable subdiv, trust me). It’s probably best you just forget I mentioned this and use the normal map method.


Ok, one more channel. This one gets a bit complicated. Up until now, our shader has been a simple dielectric shader. We now need to introduce an alternate shading path for metal, and use the metallic map to blend between them. To do this, you are going to add a mix node at the end of the chain, attach your metallic map to the mix factor, then put an extra glossy BSDF on the second input, and attach your base color, rough (from the power node) and normal (from the normal map node) to this glossy BSDF.

metallic attached

I’ve highlighted our newly added nodes in red. Areas that are dark in the metallic map will use our diffuse/glossy fresnel mix we created earlier. Areas that are bright in the metallic map will shift over to this glossy-only shader. Since metals have colored reflections, we attach the base color to the glossy-color input here, unlike our other glossy BSDF on the dielectric side. Since roughness and normals are shared, we use the squared-roughness and normals just like on our other BSDF nodes.

Wrapping Up

Here is our final monkey!


This shader setup is just the very basic elements required to translate the shader. There are numerous other effects you can add. For example, some people like the look of metal shaders that blend two glossy BSDFs at slightly different roughness. You can add that in to your shader (use an extra math node to scale your roughness map). Some people prefer to use the layer weight node instead of fresnel. It’s all up to you, feel free to experiment!

You can make a node group out of your shading nodes here (minus the image textures) so you don’t have to set this up all over again for every material. Or you can just use mine. Grab it in this post:

10 thoughts on “Importing Substance Painter texture to Cycles

    • You just need to have your normal map set to OpenGL format. In B2M, this is set under the “relief” tab. Default is DirectX, change that to OpenGL.

  1. Pingback: Starlight Ensign » Blog Archive » Substance Painter2 → Blender のワークフロー

  2. In the post you have said that all NON-RGB images must be set to non-color data, but in one of the final screenshots(the metallic one) you have set your metallic image to color data. Is that an error or is that intentional? What is the right way to do?

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s