Car Paint Tutorial - Part 4 (Reflections)
The last material layer is going to be our top coat, the clear coat. This portion of the shader was and continues to be the most troublesome. But with it’s help, our shader’s results go from this:
Keep in mind that this system is not flawless. In motion there are still artifacts from using real time scene capture, along with screen space reflections. If you have solutions to any problems you come across, please share them. I will keep this tutorial updated with the newest information, so everyone can reproduce the best results.
Before we get started putting together the reflections in the materials editor, we will need to create a new scene capture cube. To do this, head over to the Modes tab in the main editor and enter Scene Capture Cube into the search box. Click and drag a new Capture Cube in the scene and place it near your testing model. Next, go into the Content Browser folder where your shader is being stored. Right click and look for “Cube Render Target” under “Materials and Textures”
After you have created a “NewTextureRenderTargetCube” rename it to “ReflectionsCapture.” Double click it to open up the details window. In the tabs on the right you should see under Texture Render Target Cube the settings for “Size X.” By default it is set to 256. For better performance, lets change it to a smaller size: 128. Save and close out of the details window.
Our next step is to tell the Scene Capture to send its capture to the Render target. Select the SceneCaptureCube which you placed in your level. In the details tab you will notice under Scene Capture there is a box called “Texture Target.” To set it, drag and drop the ReflectionsCapture Texture into the space. You will notice that the previously green “Reflections Capture” texture is now an image.
This render target is going to serve as the source of our reflections, and also help drive the reflection mask. Open up our Paint shader so we can use this new texture.
As before, we want to create a separate material within this shader to create our last layer. Right click in the Material editor and create a new “MakeMaterialAttributes” node. Drag and drop the “ReflectionsCapture” texture into the material. Before we can use this texture on a model’s surface, we have to tell the shading system to use it a reflection.
We will do this with a “CustomReflectionVector” node. Right click in the material editor, search for “CustomReflectionVector” and place the node next to the texture. Plug the results of the new node into the UVs of the texture. This node is instructing the texture to behave like a reflection on any surface.
Reflections in car paint are not perfect mirror reflections though, so we need to tweak some of the colors of this texture. Right click and create a Desaturation node from the color tab. Plug the full color of the texture into the top module of the Desaturation node. Next, create a constant vector, with a default of .1 and plug it into the “fraction” module of the desaturation node. This slightly mutes the color coming from the capture, making the reflections a little more lifelike.
The last thing we want to do to this portion of the material is add a Parameter to control the overall amount of Reflections. Easy enough. Create a new Scalar Parameter and a new multiply. Name the parameter ReflectionAmount, set the default to 1, and plug it into Multiply B. Plug our last Multiply into the new multiply A and thats it for Emissive. Plug the last multiply into the Emissive Color module in the new Make Material Attributes node. We are using the emissive channel so that our reflections can be brighter than the surface, through direct light.
To view our latest work, plug the result of the MakeMeterialAttribute node straight into the final Material Attributes node. You can experiment moving the capture actor around in your scene, to view the real time reflections working. If you shift select the actor and your car paint test model, you can view the reflections working with the model in motion.
Back to the material editor. We need to quickly add two scalar parameters to our reflections material. This is to define the Metalic and Specular attributes. Your first parameter should be called something simple like: “ReflMetallic” set the default to 0. Now we need to do the same thing for Specular. Name its parameter ReflSepcular and set the default to 1. You can plug both parameters to their respective attribute modules.
Most car paints don’t have a flawless surface. Dirt and grime can affect how the light reflects on the surface. So we are going to add some grime to the surface. Pull the “Grunge” texture out of the resource folder provided, and drop it into the material. First thing we are going to do to this texture is reverse one of the color values. You can do this with the use of a “OneMinus” node. Create a new “oneMinus” nod and hook the red channel of the grunge texture into it. This is changing the lights to dark and the darks to light. UE4 is reading the darker colors as more smooth, and lighter as more rough. This, in turn, changes how the light is scattered on the surface, giving it more definition.
We want dynamic control over the amount of grunge. Add a ScalarParameter and a “CheapContrast” node. Name the parameter “Grounge_Contrast” and set the default to (negative) -0.1. Plug the results of the “OneMinus” node into the “In (S)” module, and “Grounge_Contrast” parameter into “Contrast (S)” module. Next, we will need a new multiply and scalar parameter. Name the new parameter “Grounge_Amount” and set the default to 3 for now. Plug “Grounge_Amount” and the results of the “cheapContrast” into the multiply. Now we have control over more of the look of this grunge texture. Lastly,. plug the results of the latest multiply node into the Roughness module of the “MakeMaterialAttributes” node. This texture will give the paint a visible layer of grime. look. Although this roughness doesn’t affect the emissive, it will affect the highlights and add a touch more realism.
The very last attribute we are going to define for the Clear Coat material portion of this shader is the Bump. What we want to simulate is Orange Peel. Orange peel is a byproduct of paint drying. When paint is drying, imperfections cause a small ripple to form. It is visible in most car paints. Very few car companies have perfected a we to avoid orange peel. Ferrari is among the best for smooth paint.
Find the Orange Peel normal map within the provided files. Drag and drop it into the material. Now, lets do something to save us a little time. We want dynamic control over the bump. In the Flake section, we created a system to increase the red and blue channels of a normal map and then, blend back the blue channel. We are going to copy and paste that portion. Copy everything from the Mask RG node to the final add node. Paste it next to the OrangePeel texture node. Connect the Normal map to the pasted section. We are also going to want to change the Parameter name from FlakeBumpPower to OrangePeel_Amount. Don’t forget to change the group to Reflections. Very last thing we need to do is define the UV Coordinates for the normal map. Because the size of your models may vary greatly, we will make it dynamic as well. Like we did with the flake mask, create UVCoordinate, ScalarParameter, and Multiply nodes. Name the Parameter “OrangePeel_Scale” and set the default to 12. Plug it and the UVCoordinate node into the multiply, and the multiply into the OrangePeel normal map texture.
Our clear coat shader is complete! Although, in the material’s current state it doesn’t look like much. The last portion of the tutorial is the creation of a mask for our clear coat. The mask is by far the most convoluted section. Before we get started, take a little time to organize your shader. Add comments for latter, make a pretty to look at shader. You might want to implement your own features, after this tutorial. Keeping things clean is the best way to save yourself time in the future.
At this point your shader should be looking something like this.
Alright! Pour yourself one more cup of coffee and get ready to finish this thing!