# Shader node reflection model setup inaccuracy?

• So we've demonstrated that with the legacy Reflect node, there is some micro-facet model in play. Could we guess that the Reflect node is actually now a "synonym" for the GlossyBsdf node in a particular setup?

Let's try it and see.

I guessed that the equivalent would be GlossyBsdf with Color white and Distribution GGX.

Looks like a match to me.

But let's try a different Distribution just to be sure.

Well - clearly it's not even slightly matching the Beckmann distribution.

I will leave it to you to experiment with other Distributions and other settings for Roughness. I tried a few and nothing was even close. I'm pretty convinced that the Reflect node is synonymous with the GlossyBsdf set to GGX.

• Let's test the first two of the original posted shaders, using the furnace.

Note that because I want both setups in the same shader, I had to make a small change to replicate the first shader. Instead of plugging the diffuse into Alternate_Diffuse and the ks_microfacet into the Alternate_Specular, I did the equivalent combination using an AddClosure. I can assure you the math is the same.

The two shaders produce different responses and it is (to me anyway) obvious why this is so.

The first (top) setup let's the diffuse node run free without modulation, and modulates the ks_microfacet reflectance using the idealized Fresnel equation.

The second arrangement (bottom) uses the fresnel factors to modulate BOTH.

In terms of math, letting S denote the specular node, D the diffuse node, and F the Fresnel coefficient for reflection, we can describe the first and second like this:

First: D + FS
Second: (1-F)D + FS

See the difference? It is no surprise that the outcome differs.

• As further evidence of the math, I make a small addition to the first (top) shader wherein I use the complement of the Fresnel reflection coefficient to modulate the Diffuse node.

And now, the two arrangments produce exactly the same result.

So it should be clear that the two shaders truly are now "basically the same", and they DO produce the same results.

• Now up top I changed to noobalien's 3rd arrangment. This is basically the same and the image shows this.

However, and this is a very interesting point, these arrangements do differ in parameterization. The 3rd (top) arrangement offers a unique opportunity to manipulate the shader in certain ways that matter towards producing a more physically accurate shader, given that the surface is not ideally smooth, but instead has roughness.

The simpler (bottom) arrangement does not let us adjust the Fresnel equation to compensate for roughness! And that is why the 3rd (top) arrangement is "better".

This is a common theme in my shaders and a common complaint by other users who perceive my shaders as overly complicated. The complication is NECESSARY to implement variations. When you look at a particular set of values (such as roughness = 0), then it is possible to remove some nodes.

But to allow for the other billion roughness values, AND maintain physical accuracy, the four-node setup is far more flexible than the three-node setup, even though they appear to be the same.

They're only the same because they're unfinished. They are both equally WRONG at the moment, but one is easier to correct than the other.

• However, we have a serious problem.

Nobody appears to know what is physically correct here.

As you noted, noobalien,

Supposedly, the roughness value should correlate to the interval between the fresnel black & white colours with grey values instead, but I can't find such reflection percentages anywhere.

Indeed. I can't find any published rules for this either. We have only a series of ever-better "plausible" theories and implementations, as well as numerous parameterizations that more or less do what artists expect them to.

I can tell you what I've used in the past, but I can also point to regimes where my roughness compensator would fall over.

But it isn't just me. I recently read a paper from Disney where they explained the latest "principled" shader and why it's better, but they still showed an impossible outcome in the furnace from what is widely considered the best shader to use by far.

Meh.

• This is pretty much what I used to manage the Fresnel effect for rough surfaces.

I add one more blender and I blend the Fresnel with a constant rgb 64 64 64, according to how rough the surface is.

This reduces the edge reflectance to be closer to the center reflectance.

But when the IOR changes, then the gray value has to change some more. When I want the gray to automatically track the IOR, I can actually use an equation from a few more nodes.

Here it is with no (black) diffuse in the furnace, with right-side roughness at .2

Here with roughness .5 and with the HDRI environment.

There is still some Fresnel effect, but much reduced.

Is it physically accurate? No, or at least I can't prove it. But it works well.

• Here it is with red diffuse.

• Note in the past I have referred to this pattern as "rough surface fresnel". I used it to make very realistic skin even in FireFly, but it was very expensive to calculate.

It found its way into EZSkin and I believe the checkbox is "Rough surface Fresnel".

• One more render and then I'm going to bed.

This is using the above shader, roughness = .1 on the left, and .2 on the right.

• When I got up and looked at this I realized I made a mistake in parameterization. Looking at that image I was bothered by the still-very-high amount of fresnel edge reflection with that much blur.

I forgot to add the squaring term I use on roughness and so does Disney. Without it the fresnel and blur don't go together, and the roughness number is too powerful and hard to use.

• With the roughness squaring term, a test render with .1 and .3 roughness looks like this

I just woke up and intended to do .1 and .2 but that is .3. Need more coffee.

Here is .1 and .2.

• I set up a comparison render here with my mat pawns. They are configured to be invisible to raytracing so the reflections are a little bit strange as they do not reflect each other, or even themselves.

Top row is using the shader above, bottom row is using Ghostship's excellent Uber 3 shader. Both are at IOR 1.45, with diffuse color 128, 20, 20.

Left to right you have roughness going from 0 to .1, .2, .3, .4, .5, .6, .7, .8, .9, and finally 1.0.

While the two shaders are clearly behaving similarly, the exact amount of rough surface fresnel reduction is slightly different. Looking this over, I judge that Ghostship's is more realistic. But I'm not basing that on anything other than looking at the top row and judging that the edge reflection looks just a little too hot in mine. I don't know the real rough surface Fresnel formula.

Same comparison, but in the furnace, with diffuse set to black. In this image you can very clearly see the behavior change for the rougher materials.

• @bagginsbill is that variation, which is most obvious at the 50% roughness mark, between the shaders, perhaps something that tweaking the power curve (yours uses x^2) or the minimum (2nd colour chip in the Fresnel_Blend node) would eliminate? I guess unless you have a meaningful, scientifically determined "reality" measurement or formula to follow, it all falls back to "what looks right" and subjectivity.

I see that your pawns have a useful mix of curved and flat surfaces to highlight such comparisons. Have you sampled the brightness of the flat upper surfaces to see whether the 10% graduations are more or less linear?

• @anomalaus

Yes it is easily adjustable. In addition to the two methods you indicated there is a third, which is to add a power curve (or it could be Math:Bias, which is the save curve but a different parameterization) between the Roughness and the Blender_2 where the Fresnel Blend is mixed with the flat dark gray. And/or a fourth method: to change the Blender_2 Blending value itself to above or below 1.

Because there is no right or wrong, it could be argued that such a curve should be a primary parameter for the shader and is motivated by additional surface properties, such as dust.

If you assume the surface isn't merely rough, but actually has some dust or fuzz, then the top row is quite plausibly MORE correct than the bottom row.

• I see that your pawns have a useful mix of curved and flat surfaces to highlight such comparisons.

Indeed - that was the motivation for making the pawn excactly as I did. It has spherical, cylindrical, and flat surfaces both horizontal and vertical, and also has round and sharp edges, and a skinny neck for observing refractive absorption properties due to thickness.

Have you sampled the brightness of the flat upper surfaces to see whether the 10% graduations are more or less linear?

No and don't expect it to be linear as the Fresnel equation is severely non-linear and so is the mix with the dark gray.

Now my shader looks a LOT like ghostship's.

Mine still has a brighter edge reflection (particularly at 60-70% roughness) but it's more subdued than it was.

• @caisson

Thanks for giving it a go! It's interesting you would use two glossy nodes and blending with 0.04 is quite elegant, simple and functional.

So now we've learnt indeed ks_microfacet uses GGX distribution in SuperFly.

@bagginsbill

I'm thankful you would say this was an interesting subject worth of attention, and now this lesson is great and quite a treat to keep me studying through the week.

When RDNA forums gone "like tears in rain", we lost so many useful documentation from there. Remembering one of your examples for a skin shader prompted me to bring back the subject here.

While the Scatter+Blinn skin was good enough, I noticed something off near the edges which didn't match what I could see outdoors but as usual, I couldn't tell 'why'. Your lesson explains it very well.

One question though, shouldn't RGB 64 64 64 be a match of .25 instead of .2?

@ghostship
Downloading the Uber Shader, thanks for all the work put into it. It'll be interesting to take a look inside and learn from its inner workings.

• One question though, shouldn't RGB 64 64 64 be a match of .25 instead of .2?

OK, ignore that. Got it now.