Car Paint Tutorial - Part 5 (Reflection Mask)
You will have to forgive me on this portion of the shader. Its is the result of hours and hours of testing and experimentation. It is not as straight forward as the other sections. The results could likely be achieved 100 different ways, but the methods I used work well, and I’m sticking will them for now.
Before we get started I would like to explain my methodology. (If you want to get started completing the shader, you can skip this paragraph.) While creating a mask for this system I considered many different methods of blending the clear coat into the other layers. Originally, I was using a separate piece of geometry with a translucent material to produce highlights and reflections. Because of translucent material limitations, I eventually decided to simplify things. I chose to use older methods from the UDK days (capture actor). Simply using a capture texture in the emissive channel of the shader did produce reflections. The problem was, the values did not represent how real paint behaves. The sun in the reflections wasn’t blindingly bright. It was muted. After a lot of testing I eventually thought to myself, why not use the capture texture to drive the opacity of the clear coat? I gave it a shot and it worked! All I had to do was refine the system. More and more experimentation lead to the system which I use now. Like I said, there are probably a hundred different methods which would work, maybe even better. One portion of the shader that is still lacking is the orange peel effect. Normal maps don’t affect emissive so orange peel normal map doesn’t change the look of the reflections produced by the capture. I have considered using methods to improve the effect, but unfortunately I have to move on to other projects. If you have a method which works, please let me know! I will update and credit you with the improvements. And that goes for any other improvements you wish to share! There is a lot of potential for improvement of this shader. Like a new layer for rust, using textures for the color channels, better normal maps for flake. If you are new to shaders, by now you should have a better understanding of the material editor. Before this project I had very little knowledge in creating advanced shaders, but now I love material creation! Keep experimenting and be ambitious. You will be rewarded with beautiful art and a mastering of the trade. Now, let us finish this thing!
The first node we are going to create is a new “MaterialBlend_Standard” This node is going to blend the results of our first blend with our top clear coat. Connect the results of the first blend node to the “Base Material (MA)” module. Then connect the results of the clear coat “MakeMaterialAttributes” node into the “Top Material (MA)”. You Can now plug the results of our new blend directly into the final “Material Attributes” node.
Next thing is to find a space where we can construct the new mask. I chose to build above our last one. Copy and past the “CustomReflectionVector” and “TextureSample” node from the clear coat section. We will be using this texture to help drive the opacity of the mask. The first thing we want to do with this texture is to decrease the contrast so that more of the reflections come through the mask. Create a new multiply node and a standard constant node. Set the constant default to 4. Plug it and the blue channel of the texture into the multiply. Now create a new Lerp node. Plug the results of the multiply into the Alpha of the Lerp. Next, we are going to change the defaults of both values of the Lerp. You can do this easily by selecting the Lerp node and heading over to the details panel on the left. Under Const A, set 1.5. Under Const B, set 2.0. Once finished, right click on the Lerp node to bring up the options menu, select “Start Previewing Node”. This will render the results of the node you right click on, on the sphere in the top left hand corner of the material editor. This comes in handy when developing a system. When you want to get out of this view, just right click on the node again and select “Stop Previewing Node”
You will notice that the mask values are overblown, but with the correct contrast. To dial the values down, we will multiply the results by a small value. Create a new: Multiply node, a standard constant, and a scalar parameter. Name the parameter “ReflectionAmount” and set the default to 1. (This will actually be a copy of a parameter we used in the clear coat section. If you would prefer, you can copy and paste it from there.) Set the value of the standard constant to 0.05. Plug both the Parameter and constant, into the multiply node. This gives us control over a very small value, dynamically. Create another new multiply. Plug the results of the previous multiply and the Lerp into this node and we have a mask with correct values.
To illustrate how affective the mask is in its current state, go ahead and plug the results of the last multiply into the alpha module of the second “MatLayerlBlend_Standard” You might be surprised about how good the reflections already look!
There is one last important part of car paint reflections which is missing. The fresnel. Car paint, like most surfaces, is more reflective when viewing with a shallow angle. When you look at car paint head on, there is much less reflection.
Here is an example of the reflections without fresnel:
And with fresnel:
So let’s make a Fresnel node. Remember to use the VecorOps variation. We are going to want dynamic control over the power, so create a new “scalarParameter”. Name it “Fresnel Power”, set it’s default to 2.5, and add it to the reflection mask group. Now that we have a fresnel, we want to have dynamic control over it’s extremes. How bright the bright can be dark the darks. And, we will once again want dynamic control so we can fine tune the reflection values. Create a new Lerp and two Scalar Parameters. Name the first Parameter “ReflectionMaskFresnelA” and the second “ReflectionMaskFresnelB” Set the value of “ReflectionMaskFresnelA” to 0.02 and set “ReflectionMaskFresnelB” to 0.9. Plug them both into their respective modules in the Lerp and use the fresnel as the Apha. So now, this Lerp is defining the lowest amount of reflection to 2% and the highest to 90%
Now that we have our fresnel we need to blend it and the reflection capture together. On more multiply will do the job. You can view our progress by hooking the latest multiply into the “MatLayerlBlend_Standard”, once more.
Now you will notice that the reflections have decreased dramatically. And, the fresnel effect isn’t very pronounced. And, highlights are basically gone when looking at the surface head on. Don’t worry, we are going to fix all of that right now.
At the moment, our fresnel is acting as a mask for the capture texture. We certainly want this, but we also want more of the fresnel to come through. So we are going to add the fresnel into what we already have, again.
Create a “Power” node. This is going to give us the ability to change how effective this fresnel boots is going to have. Essentially it will define the opacity of the clear coat. Plug the results of the Lerp attached to the fresnel, directly into the “Base” module of the Power node. Create a new ScalarParameter and name it “ClearCoat_Opacity”. Set the default to 1 and plug it into the “Exp” module of the power node. To add this to the rest of the reflections we will use an Add node. Place the node and plug “Power” and our last multiply into it.
Connect the add results into the Material Blend to view its results once more. Alright! Our fresnel is boosted and it’s looking great. Highlights are the very last portion we need to boost. Currently, highlights where the fresnel it at its dimmest, are also dim. That is because we are using the fresnel as a mask for the reflection texture. But the sun doesn’t care about fresnel. The sun shines brightly and clearly on the surface of car paint, no matter what angle you are viewing it on.
We are going to add the sun back into the mask. This, I promise, is the very last function we need to create. After this it’s all done. If you have gotten to this point in the tutorial you are a champ! You are minutes away from completing this puppy. 11 more nodes and we are DONE!
To boost the highlights, we will need to reference the Reflection Capture texture once more. Create a new “Power” node and plug the red channel of our texture into the “Base” Module. Create a new constant vector, set the value to 2, and plug it into the “Exp” module. This power node is essentially increasing the contrast of the texture. Once again, we want control over this value, so create a new: Multiply, ScalarParameter, and ConstantVector. Name the parameter “AddedHighlight” and set the value to “0.5” Set the value of the constant to “0.01” and multiply it with the parameter. Now we want to multiply the power with this parameter controlled multiply. Create a new multiply and plug them both in.
Because we might want to create an instance of this shader without reflections, we need to make sure to multiply this highlight boost portion, by the same “ReflectionAmount” we used earlier. Copy and paste the parameter next to our highlights work. Create a new multiply and connect the “ReflectionAmount” node as well as our last multiply into this new node.
Three more nodes everyone! Now we need to add the highlights back into the other reflections. Create an add node and hook the systems up. Finally, create one last multiply and one last ScalarParameter. Name the parameter “MaskPower” and set the default to 1. Plug it and our last add into the multiply. And very lastly, plug the multiply into the MatLayerBlend alpha. Save your work! You are done!
You are now the creator of a power tool which can simulate hundreds of different types of car paints!
Every instance of this material you make can be totally unique. Spend some time playing will all of the custom parameters we set up. If there is an aspect of the paint you want to change, it is likely that we have a parameter in place to change it.
I hope you have a lot of fun using this system in your work! Please email me if you have any trouble, questions, comments, whatever. My email is firstname.lastname@example.org
I would love to see how you use this shader for your own game. Good luck and thanks!