Car Paint - Part 2

Car Paint Tutorial - Part 2 (Flake)

In the previous section, we spent some time creating a simple base coat for our system. If you skipped ahead to this section, it should be easy for you to replicate this shader. If you are coming here from the first section, take a stretch break and pour yourself some coffee because things are about to get real.  

There is a folder containing all the textures for this tutorial, as well as a model to test on. Please feel free to use them however you need.

I believe that it is extremely useful to start using parameters and testing your shaders with instances very early on. It will save you a lot of compiling time. Our shader is going to be segmented by coat and function. To do this, we will be using multiple “MakeMaterialAttribute” nodes. Later, if your choose, you can reorganize the shader to eliminate multiple uses of the node.

The very first thing we are going to want to do is encase our base shader in a comments box. I like to keep shaders as clean and organized as I can as a courtesy to anyone else who might need to poke around later. Create a comment box around the entire base shader, including the “MakeMaterialAttributes” node and move it to the side. Then we will need to make a new “MakeMaterialAttributes” node  for our next coat of paint: the flake. So that we can see what kind of effect the metallic portion of our shader will have, override the previous “MakeMaterialAttributes” node with our new one.

Car Paint flake come in a head spinning number of varieties. Size, shape, color, and density are often different, which can greatly change the look of the surface. We will be creating a system which can dynamically change these attributes. After instancing, you will be able to emulate most types of metallic paints. Nearly every metallic paint uses aluminium flakes. So lets start there.

First, lets define the metallic property of the flake. Because it is unlikely that we will want to change it later, create a standard constant with a default value of 1 and hook it to the Metallic attribute in our new “MakeMaterialAttribute” Node

Next, let’s define the color of our flakes. Like the base coat, we will use two “vectorParameters,” a “Fresnel” and a “Lerp” node. When creating a fresnel, try using the VectorOps variation. In my testing it’s effects and ease of use are more favorable.

Name the first “VectorParamter:”  FlakeColor_Saturated and the second FlakeColor_Dark. Hook  “FlakeColor_Saturated” into the Lerp “A” and “FlakeColor_Dark” into Lerp “B”. In my testing it wasn’t necessary to use anything but the defaults of the fresnel, so you can hook it directly into the Lerp “Alpha” I recommend setting the default of the “FlakeColor_Saturated” to either your favorite color, or one that you see regularly. My car has blue metallic paint, so I will set it to a saturated blue.

Now let’s take a look at the material on our model using an instance. It’s fairly simple at the moment so there isn’t much to play around with yet. Let’s fix that!

After you have had a minute to set up an instance to test with, let’s affect the color further. The next thing we are going to want to do is add color variation to the flake. Find the texture “Noise2” in the texture folder and drag and drop it into our material. Create a new “scalar parameter” and name it “FlakeScale” and set its default to 12. Create a “UVCoordinates” node and a multiply node. Plug “UVCoordinates: into Multiply A and “FlakeScale” into B. Create one more Multiply node and a Constant node and plug our previous Multiply into the new Multiply “A” and the constant into “B.” Set the new constant to 0.3. The reason we are doing this is avoid Nosie2 lining up with the layer mask we will create later, using the same “FlakeScale” parameter and texture. Plug the last multiply into the “UVs” of “Noise2” and then hook the red channel of “Noise2” into the “Alpha” of a new Lerp node. Then create one more “VectorParameter” which will act as our light spotted color. Name it “FlakeColor_Light” and plug it into the “B” of our newest Lerp and plug our previous lerp into our new lerp “A.” Hook the newest lerp into the “BaseColor” and your shader should now look like this.

Roughness of the flake is another attribute we don’t need much control over. Create a “ScalarParameter’’ named “FlakeRoughness” with a default of 0.3.

The next aspect of the flake coat which we need to define is the Bump. All metallic paint has variation in the orientation of the aluminum flakes. The bump in this shader is going to be able to control that sparkle effect.

The normal map you use could be range from a custom map which simulate the light reflection angle precisely, to a random noise map. Whatever map you choose to use, it will be useful to adjust the amount of bump is added to the flake layer.

The way we are going to do this is by isolating the red and green channels from the map, adding a scalar parameter to boost or lower those values, and then add the blue channel back in.

Let’s grab our normal map (Noise_Nor) and drag it into the our shader. Add a “textureCoordinate” node. Set the tiling to something relatively high, 15 should do for now. Then you are going to want to create a new multiply node. Plug the TextCoord node into the multiply module A and create another new multiply and plug it into our first multiply’s module B. Create a copy of the “Flake_Scale” parameter and plug it into our new multiply A module, then create a new standard “constant” with a value of 0.8, and plug it into module B. What this is doing is making the output of “flake_scale” marginally larger. When applying our noise normal map, it will be important for the bump to be slightly larger than the flake mask, which we will get into in a little bit.

For now, we need to remove the blue channel from the texture. Grab a component mask and plug the output of the texture into it. Next we need to assign a number to the blue channel so that our system behaves properly. Add an “append” node and a standard constant node. Plug the result of the mask into the first module of the append node and the constant, set to zero, into the second module. Now we have our red and green channels separated and next we want to control the power of these channels. Add a multiply node and a “scalar parameter” node. Set the default of the scalar to (1) and name it “FlakeBumpPower.” Next use the output of our appended texture to the multiply along with “FlakeBumpPower.”Great! Next we need to do is add back the standard value of blue, before we can plug in our bump. Create a “Constant3Vector” node and set it to 100% blue. Then create a add node. Add the appended texture to the blue channel and we are done with bump. Plug the result of the final add into the “Normal” module. And that’s it for bump and our aluminum flake system. Don’t forget to encase the Aluminum portion of our shader into a comment box, for better organization.  

In the next section, we will be creating a masking system for our flake shader.