Car Paint nodes explanation

Post your tutorials and help questions in this forum
thomas
Posts: 348
Joined: Tue Aug 31, 2010 9:59 am

Car Paint nodes explanation

Post by thomas »

Hi all,

By request of Lightwave3D (the Kray user, not the software), I'll share a little "car paint" nodes setup here. Let's start simple and expand on this in next steps. The result of this first step is shown here:
Car Paint Test 02.jpg
Okay now. Nodes always look complicated at first, but when you start to break things down into smaller components they are usually fairly easy to follow. Let's give it a try!

Basically what is going on in car paint is that you have a top coat of glossy varnish, and underneath is a paint coat in the color of the car, often in metallic paint. The top coat is very glossy, and the bottom paint looks very "matte", or with a very blurry reflection.

Explaining this in another way: a ray of light hits the top varnish coat of the car first. This coat is transparent, so the situation is simple: a part of the light is reflected, and the part of light that is not reflected is allowed to continue on and hit the second layer, the paint coat.

So let's recreate this using nodes!!!

First of all, you'll see in the node tree, that there is a ClearCoat fresnel calculation on top. This give the correct amounts of reflection for the glossy top coat, with an index of refraction of 1.45. The ClearCoat reflection is perfectly sharp, so we create a reflection "shader", and we multiply the fresnel value with the reflection shader (of the ClearCoat) which results in the correct total reflection for the glossy topcoat.

Let me explain a bit more why I work like this. The fresnel value tells lightwave HOW MUCH reflection there is for a given spot on our object, but not how sharp or blurry the reflection is. The reflection shader tells lightwave HOW SHARP the reflection is for a given spot (and how it is colored, and how much glancing stretch if you use this), but not how much reflection there is. To get the final reflection, you need to multiply HOW the reflection looks with HOW MUCH reflection there is. That is what the "ClearCoat Total Reflection" multiplier does. This multiplier is a VECTOR multiplier, because the reflection shader expresses a color value (RGB), and if a value has more than 1 component, you need to use a vector multiplier instead of a simple scalar multiplier.

Okay, now let's do exactly the same thing for the paint layer that lies under the glossy topcoat (the ClearCoat):

Create a Fresnel node ("Paint Fresnel"), with a value of 2.2 for a nice metallic reflection value, and create a reflection shader ("Paint Reflection (Blurry)") with blurriness set nice and high. I use the reflection shader from DP Kit, and I suggest you do the same because it allows you to set the number of samples you want to use, which is always handy. I set the blur amount to 250% and samples to 10. If you use the native LW reflection shades I think blurriness of 60% is okay (the value for the DP Kit reflection shader always needs to be a lot higher for the same effect).

Then, turn on the "tint refractions" for the reflection shader of the paint (I know, that should be "tint reflections" but it's spelled wrong in the node), and create a color node with the paint color. Then connect this paint color node ("Paint Color" in my setup) to the color input of the reflection shader for the paint. Now, as we did for the clearcoat layer, use a vector multiplier node to multiply the AMOUNT of the paint reflections with the SHADING of the paint reflections ("Paint Total Reflection").

Okay, now we have TWO reflections: one for the top glossy clearcoat, and one for the paint coat. We are going to add these two together, but first we need to make one more change to keep things "physically accurate", sort of:

The top coat get 100% of the light that falls on the surface. The paint coat however, does not get all of the light, because a part is reflected on the top coat. This means that only the part of light that is NOT reflected from the top coat goes on to the lower paint coat! Luckily the fresnel node has a handy "Inverse" output, that outputs the inverse of the reflection value, and this is the amount of light that goes on to the paint coat. If, for a given spot on the surface, the top coat reflection is 20%, then 80% of the light goes on to the paint coat. In this situation the fresnel result for the top coat would be 0.2 and the inverse would be 0.8. Since only the 80% (in this case) goes on to the paint coat we need to multiply the light going to the paint coat by 0.8.

This is hard to do with nodes, but that is no problem: we can also just multiply the output of the paint coat by 0.8, or better said by the inverse of the top coat fresnel value (since this means "the amount of light not reflected, so going through to the paint coat").

So, we need to multiply both the "Paint total reflection" node, and the inverse value of the "Paint Fresnel" node by the inverse of the ClearCoat fresnel. By the way: the top coat was 100% transparent, so there the inverse fresnel value meant how much light was let through the transparent coat. The paint coat is 100% opaque, so here the inverse fresnel means the diffuse value (= everything that is not reflected).

And that's about all I need to explain. So the paint fresnel INVERSE value (= the paint diffuse component) is multiplied by the ClearCoat inverse fresnel value, and the the paint total reflection is also multiplied by the same ClearCoat inverse fresnel value. The diffuse value can use a simple scalar multiplier, because it multiplies two scalars, but the "paint total reflection" is in RGB value so needs a vector multiplier.

Then the end is simple! Connect the base paint color to the color input of the final Surface node of the material, connect the multiplied diffuse of the paint coat to the diffuse input of the surface, connect a scalar 1 value to the reflection input of the surface node, and add the ClearCoat Total Reflection and the multiplied Paint Total Reflection (= "Paint Reflection * "rest" lighting) with a vector add node, and connect this last one to the Reflection shading input of the surface.

That's it! My fingers are tired :D

Object, scene and surface attached. Any questions?
Attachments
Car Paint Test 02.srf
(48.29 KiB) Downloaded 267 times
Car Paint Test 02.lws
(8.86 KiB) Downloaded 247 times
Car Paint Test 02.lwo
(961.84 KiB) Downloaded 283 times
thomas
Posts: 348
Joined: Tue Aug 31, 2010 9:59 am

Re: Car Paint nodes explanation

Post by thomas »

Here's the node tree, by the way.
Screen Shot 2016-03-09 at 00.37.22.png
thomas
Posts: 348
Joined: Tue Aug 31, 2010 9:59 am

Re: Car Paint nodes explanation

Post by thomas »

By the way, the surface above is a "conservative" but more or less physically accurate metallic car paint. In the next steps we can add more control to make the surface more extreme, which is more interesting visually, but less physically accurate.
thibault
Posts: 57
Joined: Wed Nov 18, 2009 5:39 pm

Re: Car Paint nodes explanation

Post by thibault »

Thanks Thomas !
ZodiaQ
Posts: 232
Joined: Mon Mar 25, 2013 4:52 pm

Re: Car Paint nodes explanation

Post by ZodiaQ »

Wow Thomas, thx so much for sharing this!
User avatar
Janusz Biela
Posts: 3265
Joined: Mon Mar 13, 2006 10:39 am
Location: Finland
Contact:

Re: Car Paint nodes explanation

Post by Janusz Biela »

Of course you must be careful with this. This is not shader and it will be situation when you will get deep recurse on this surface. It will affect very long render - in some situation when surfaces will reflect each others the time render can fail.

This problem can be solve (partly of course, because only in Core of render engine it can be optimized by dynamic reflection recurse, some reflection trick, etc.) by adding reflection limiter:
Car_Paint_Test_v03.srf
(49.51 KiB) Downloaded 279 times
where reflected surfaces has forced limit of reflection for maximum two.
Of course this half solution because if that surface will be behind 2 or more glass layers you will see black surface. And again that must be done in Core Engine by special shader which detect fail reflection and add dynamically more.
Also Double Reflection must be calculated differently - because now in Node both reflection must be calculated separately which means double and more time render. So shader will solve this problem by special code and reduce calculations.
thomas
Posts: 348
Joined: Tue Aug 31, 2010 9:59 am

Re: Car Paint nodes explanation

Post by thomas »

Hi Janusz,

How exactly does your recursion limiter work? I get the feeling that it does this, but I'm not sure:

1) The spot info gives the number of bounces for a given ray
2) The logic operator in your example surface says: "If number of bounces is lower than 2 then output value 1, else if number of bounces is 2 or higher then output value 0".
3) And the reflection probably stops being calculated when the input for the reflection in the surface node is zero.

Is this correct?
User avatar
Janusz Biela
Posts: 3265
Joined: Mon Mar 13, 2006 10:39 am
Location: Finland
Contact:

Re: Car Paint nodes explanation

Post by Janusz Biela »

just make two metallic spheres and add this limiter. Under LW VPR you will notice changes in reflection regions (when two surfaces reflect each others).
When you will put one reflection limit, then reflected part will become dark. Then more recurse the better reflection effect but...after 3 times you will notice very slight changes.

You do not need many reflected recurse on the object. All render engines use this effect for limited reflection. You can image Maxwell render (pure Path Tracing) when it must calculate Path tracing reflection and GI over 5 times? - it will fail time render.

Personally I use maximum 5 for all surfaces because I use 20 bounce lights in Kray and I do not need render 20 times reflection. This save a lot time. Of course for surfaces with low reflection (plastic) even 2 reflection recurse is enough because second reflection is so weak and you will notice it. But as I told you I keep 5 because to avoid accidental problem with glass surfaces. Recurse 5 in some situations is not enough but in Kray 2 Core do not exist "detector" for fail recurse. So if scene has a lot glasses (cabinet with glass door and behind another glass) then I use in limiter 10 recurse at least or I try use only one layer of windows glass.
thomas
Posts: 348
Joined: Tue Aug 31, 2010 9:59 am

Re: Car Paint nodes explanation

Post by thomas »

Hi Janusz,

Thanks for the info and explanation. That's cool, because it actually allows us to input a "termination" color for refraction in LW, if we want. The power of nodes! :D

Of course this node tree is not optimised for speed and can be improved a lot. And most of all, of course a native shader is able to do all of this a LOT faster and more optimised.
Last edited by thomas on Wed Mar 09, 2016 3:14 pm, edited 1 time in total.
thomas
Posts: 348
Joined: Tue Aug 31, 2010 9:59 am

Re: Car Paint nodes explanation

Post by thomas »

Okay,

Here's an updated node with:
- Boost for sharp reflection (looks good, but not physically accurate)
- Boost for paint reflection (same as above)
- Fancy incidence angle base color (for those funky color shifts)
- mix in white, for the tinted reflections
- Flakes
- recurse limiter

Here's an example of the renders. The second images really shows the metal flakes working well. All files attached as well.
cp3.png
cp3B.png
Attachments
Car Paint Test Flakes.zip
(1.22 MiB) Downloaded 262 times
thomas
Posts: 348
Joined: Tue Aug 31, 2010 9:59 am

Re: Car Paint nodes explanation

Post by thomas »

Janusz,

I have some more questions for you, oh great master of nodes:

LW renders the sharp reflection different than Kray. LW doesn't use the flakes shaders bump for the clearcoat reflection, so it is sharp. Kray DOES use the flakes bump for the clearcoat reflection as well, so it becomes blurred / noisy.

It probably has to do with my bump / normal map trickery. I've noticed that the normal nodes don't really behave predictably. Sometimes the normal map only works when you connect bump as well, or the other way around etc...

In essence, I actually wanted to use the flakes texture to modify the normal value of the surface and use this to drive the flake metallic behaviour, and not use bump - because bump is much less flexible because it is across the surface in all aspects.

Do you have a good way to convert a bump map to a normal map, or something similar that would allow me to NOT use a bump map. I didn't want a bump map in the first place because that only allows for "pseudo" height levels, while I wanted to change the orienation of the metallic flakes using a procedural shader.
Fabian-Eshloraque
Posts: 74
Joined: Sun Nov 17, 2013 3:29 pm

Re: Car Paint nodes explanation

Post by Fabian-Eshloraque »

Hi Thomas,

If you want I can have a look at your car shader. I know its a LM (layered material) but its not easy to setup physical correct. This is because your shader is based on 4 layers of paint: (based on what I can see on Discovery GasMonkey show)

1. Grey matted paint - reflective blurred base layer
2. Color layer - medium reflection blurred
3. Flakes = physical flakes sprayed on the surface
4. High reflective clearcoat finisher paint - like glass

It depends on how far you want to go.

Best!
thomas
Posts: 348
Joined: Tue Aug 31, 2010 9:59 am

Re: Car Paint nodes explanation

Post by thomas »

Hi Fabian,

The car shader isn't really something I need at the moment, it was just a mock-up because Lightwave3d was asking why nodes were better than the regular texture editor, and I thought it would make a good case pro nodes.

Still, if you feel like going over the shader to make some improvements, feel free!

Regarding the layers, I simplified things a lot by going for only two layers: a metallic flaky layer as substrate, and the clearcoat varnish.
User avatar
Janusz Biela
Posts: 3265
Joined: Mon Mar 13, 2006 10:39 am
Location: Finland
Contact:

Re: Car Paint nodes explanation

Post by Janusz Biela »

Here is very interesting info. I sent this also to G. because this must be done in code It can be done by Nodes but it will be dangerous for time render or errors in PM.
Apparently I do not remember where from I got it so sorry for no credits (to whom):
lmDiagram.jpg
Target for Shader (done inside Core Render as part of code and communicate with user by GUI - plugin) is: fast render, flexibility, no errors, easy control.
Double reflection effect is complicate simulation, same like velvet and this must be done as shader. But of course not having it, good idea is to create something in Nodes, at least something similar looking.


Ok you posted already this image :lol:
thomas
Posts: 348
Joined: Tue Aug 31, 2010 9:59 am

Re: Car Paint nodes explanation

Post by thomas »

hi Janusz,

Yep, I just saw this in Fabian's post. Very cool stuff. Not sure why writing a shader for this is so difficult, since for most use cases the main calculation is:

1) Calculate reflection for a sampled spot on the top layer
2) Take the leftover light energy and colour of the ray that continues on down, and use this to light the second layer.

There are of course, as always, extreme use cases and very special phenomena at these boundaries, but for 99% of varnished two-layer materials the implemenation seems pretty feasible - along the lines of what I did in my car paint node tree.
Locked