In the last post, physically based rendering and Blender materials, we looked at how the principled shader really works. We lay the foundation for our future material creation in Cycles and for Eevee when Blender 2.8 finally arrives. Here, we will take a close look at how this is all implemented in the node editor using image textures to power the principled shader. This setup will then be supported by various other nodes to give us a system to work with when layering different materials on top of each other.
If you missed the previous post here is the summary and key take away points when using the principled shader in Blender.
For any material that we can power with a set of image textures that are prepared for the metallic workflow, the system that we will discuss here will work very well and be very efficient.
If you want to follow along you can read the next section or skip to the “Brick texture and concrete combination” section to get right into the good stuff.
For demonstration and testing we will be using a set of image textures that is provided here:
bricks_texture_example_assets.zip
They are provided under the cc0 license originally from cc0textures.com. The hdri is also licensed under cc0 and collected from hdrihaven.com.
For this workflow guide, we will be adding a sphere, and UV unwrap it with the sphere projection option while viewing the sphere in orthographic view from the front by hitting number pad “5” followed by “1”. Also, add a material slot and name it.
Position the camera and set the resolution to a square like 1024 by 1024 or maybe 1920 by 1920. Move the resolution up from the default 50% to 100%.
Next, we will enable the node wrangler addon by going to user preferences. “ctrl+alt+u” for the keyboard-oriented Blender artist. Go to the addon section and start typing “wrangler” to filter the list in real-time. Check the box next to the node wrangler addon, hit “save user settings” and we are set so far.
Last preparation will be to add the hdri image. Go to the node editor, select environment material on the earth icon and add an environment texture node. Browse for the image and add it. If not already selected, select the environment texture node and hit “ctrl+t” This will add a texture coordinate node and the mapping node. This is a function of the node wrangler addon. Using the z rotation in the mapping node we can now rotate our hdri.
Enough with the boring setup stuff, let’s get on with the show!
Our example will be a brick texture where we want to introduce patches of concrete where the bricks have fallen off. We will also add some dirt. Each layer will be added in a slightly different way because of their role in the full material. What we need to remember here though is that this is not a guide to create a brick material. We are here to learn a highly customizable and flexible system for creating materials that we can use repeatedly for most materials.
The image below shows the basic setup for a dielectric PBR material with the standard maps.
We can add this setup quickly by selecting the principled shader and hit “ctrl+shift+t” and select all the maps that we need for the material. If the maps are named properly, the node wrangler addon will set up the rest for us like this. We don’t have to worry about what image textures should be set up for color or non-color data, the normal map will get its corresponding normal map node etc. If we have other maps, like a metallic or specular map those will also be added incorrectly. A displacement map, however, will be added for the displacement input of the material output node. We can, however, skip the displacement or combine it with our normal map through a bump node like this.
Our brick material is done. The first combination will be with a concrete material. Start by duplicating the principled shader and use “ctrl+shit+t” again and this time select the color, roughness and normal maps for the concrete material. The new concrete will be added above the bricks in this example.
At this stage, we will combine the two materials with a mix shader and get a very ugly mix between the two. Instead of blending the materials we want to tell what material goes where and for this we will use a mask. A mask is just a black and white texture. We can use any image, procedural texture or combination to create the mask, but we will go with the simplest possible and use the procedural noise texture node as the mask. Add it, select it and hit “ctrl+t” to automatically add the mapping and texture coordinate nodes. Then connect the noise texture to a color ramp node before connecting the color ramp to the fac input of the mix shader. This is what it looks like.
To tune in the mask, it is easier for us if we set up Blender with a layout like the image below. We have a rendered view with the render border active to minimize the screen area we need to render. Create it with “ctrl+b” and clear it with “ctrl+alt+b”. To the right, we have the nodes we need to work with available as well.
Use “ctrl+shift+mouse click” on the color ramp to create a temporary view of what the node outputs. To reset the view back to our material “ctrl+shift+mouse click” on the mix shader which is the last shader node in our material chain before connecting to the material output node.
Bring the two flags of the color ramp close to each other to create a high contrast map. Also, change the details value of the noise texture to 16 to create a more natural border between black and white. Now “ctrl+shift+mouse click” the mix shader to preview the mix we created. From here only tweaks remain until you are happy with the result. For me, I went ahead and inverted my color ramp and set the scale of the noise texture to 3.
This combination of materials was easy enough. It is the basics for combining any PBR materials in Blender. From here we can take any principled shader and all the nodes connecting into it and group them and throw the group into any other cycles material for combination with other materials. All we need is a set of three maps for each material and a mask to tell what material goes where.
Next, we will look at how we can combine this with a material that needs a very specific placement on top of our other materials. We will add some leaking effects that should start from the top and fade out as it comes further down our sphere. We will require a new specific UV map for this effect as well as a mask that masks out the exact area for the effect. In this case, we are lucky enough that a mask image is provided so we will use that. However, this is not always the case and sometimes you will have to create your own or tweak an alpha channel and use that as a mask. We will look at how to do this as well.
Let’s start with adding a new principled shader and import the leaking set of textures. Then add a mix shader between our existing mix shader and the output node. Connect the leaking principled shader at the empty slot and we should get this.
Now delete the texture coordinate and mapping node for this newly added material and add the UV map node. With this, we can specify a new UV map. Though we will need to create it first.
If you are not very familiar with UV maps, just follow along. It won’t be a very hard process. Remember, this is a system that should be easy, right? It may seem daunting right now but trust me, it is the same operations over and over with slight tweaks and adjustments. You already know the basics.
Start by bringing in a uv/image editor and in the properties panel, go to the object data tab that looks like a triangle and click plus in the UV maps section. This will add a copy of our original UV map. I chose to rename mine to “leaking”. Fill in the name in the UV map node that we added previously.
If we select the new UV map we can alter it. We can scale down the parts of the mesh that should not have any leaking effect and hide it in a black area in the image and the parts that should have the leaking effect is now adjustable with pixel precision inside the uv/image editor.
My leaking UV map looks like this for now since I want the effect of most of my sphere and the top and bottom will not be visible in the image.
Back in the node editor, we will add some nodes for our mask image that we happened to have in this case.
You can see that we have the same concept as before, only this time we have an image mask instead of a noise texture and therefore also UV coordinates to power it. The color ramp is adjusted based on the images values. The important things to remember here is to use “ctrl+shift+mouse click” to preview the color ramps output and adjust it accordingly. In this case, I did not want the mask to go from complete black to complete white, so I darkened the white a bit so that the underlying material would come through slightly.
If we needed to use the alpha mask instead we would use that instead of the mask and the node editor would look like this.
We can also just use the image color itself and collapse the black and white range to generate a mask. It could look like this.
Note the shift from using the alpha output from the image texture to the color output since we may not have an alpha channel to work with.
At this point, we have arrived at additional tweaking. Usually, I tweak each material to look the way I want it right after adding it and before adding in the next one. However, I figured that it would be easier to follow if we left it for the end.
We are going to look at a couple of ways to add flavor to our material before we go to the summary. The most noteworthy tweaks is introducing some color variation to the individual materials and a way to create a more distinct border between our bricks and concrete. We will also tweak the roughness.
Let’s start by adding some color variation to the bricks. Zoom in to the part of the material where the bricks live and look at the color map. To introduce some variation, we will have to first create the variation and then mask where the variation should be applied and where the original color should live. We can do this in a pretty similar way to how we have done it with the mix shader earlier but this time with a mixrgb node. The mixrgb node will serve as the mixer. Though we still need something to mix and a way to mix. Add a hue/saturation/value node to generate a slight variation to our texture. I will set mine to these values.
Now we have a fac input available in the mix shader where we will use the same trick as before. Combine a noise texture with the details set to 16 with its corresponding texture coordinate and mapping node using “ctrl+t” while selecting the noise texture. Then add a color ramp between the noise texture and mixrgb. Collapse the color ramp to bring it to the black and white mask that we want.
This is how I ended up setting up the color variation for a very slight difference in color across the surface.
You have quite a lot of parameters at your disposal to get the noise the way you want. You can adjust rotation, location and scale for any single axis in the mapping node to get a stretched or just different effect. You can also try using object or camera coordinates to generate different noises. You can also try to add more flags to the color ramp and play with those values to have complete control over the transition between light and dark.
For this part, we will drive our effect from the mask separating the bricks from the concrete and then feed it through a bump node that we combine with the existing normal map data in the concrete material. Look at the edge between the bricks and the concrete in this image to see what effect we are after.
If you have ever used a 2D image manipulation program like photoshop, gimp or affinity photo you know that you can select part of the image and have the marching ants show the way, right? We will kind of do the same here now, but we will mathematically tell Blender what parts we want to select, again using masks. Right after the mask dictating over brick vs concrete distribution add an invert node to invert the mask and then feed it through a new color ramp. These nodes should not have anything connected to their outputs right now. Instead, hit “ctrl+shift+mouse click” to see what the color ramp output looks like.
Move the black flag of the new color ramp towards a position of 0.6 or 0.7.
Add a new mixrgb node and set the blend mode to “linear light”. Connect the new color ramp in the top socket and the color ramp from the first color ramp in the second socket. Then add another color ramp after the linear light mix node. It will look like this.
Bring the white flag of the new color ramp to about position 0.2 to collapse the gray tone that the linear light left behind.
Now add a bump node in the concrete material between the normal map node and the principled shader. Then connect the last color ramp in the chain to the height input of the bump node and the effect is done.
We now have something like this.
A material is never finished. We could continue to add color ramps between the roughness maps and their corresponding principled shader or we could add variation to the leaking texture color for example. There are many possibilities.
The big takeaways from this article is not the bricks or the concrete but the flow of nodes. This way we can easily take a material or a mask and create a group out of it and have a very easy and flexible system to work with in order to layer different materials on top of each other. We can also present the material much easier. Take a look at this for example. Here I have created groups by selecting nodes and using “ctrl+g” to group them and renamed the groups in the “n” panel. Using this way of creating materials gives you a very good way to reuse groups of nodes.
This is a very solid foundation for building your materials and it is also compatible with the upcoming Blender 2.8 version and its real-time engine Eevee.