20
$\begingroup$

When it comes to recreating the shading of metals like chromium with such extreme reflection curves it's obviously inaccurate using one averaged reflectance curve. Also eye-balling the values appears impossible so it becomes relevant creating individual curves as accurate as possible.

enter image description here
Source: http://refractiveindex.info

Looks like feeding in a RGB Curves node is the way to go. However I can't figure out how accurate this mechanism is. What approximation model cycles is using? Schlick's approximation? Is there anything else to consider like shifting the incidence angle?

Q: How to build an accurate fresnel curve based on the data of refractiveindex.info?

$\endgroup$
14
+100
$\begingroup$

Here is the Fresnel Conductive OSL node done in pure Cycles nodes:

enter image description here

The node noodles:

enter image description here

And .blend with linkable/apendable group if you feel lazy to build this:)


Notes:

In reality the IOR is computed like this:

IOR = N + Ki

where N is Refractive index and K is Extinction coefficient. For dielectrics, the complex part can be omitted, so N becomes the IOR. However metals do have the complex part.

You get the measured N and K values from here: https://refractiveindex.info/. The problem is, that both N and K depend on the wavelength of light.

So to render metals correctly, Cycles would have to be a spectral renderer taking into account the polarization and wavelength of light.

The best we can do is to approximate and sample just for red, green and blue light.

As per the Vray OSL reference the red, green and blue values are taken at 0.65, 0.55 and 0.45 micrometers. Put the wavelength value in there and read N and K:

enter image description here

The usage is same as in Scott Milner's answer. This is how the Conductive's Fresnel output can look like (with extreme values):

enter image description here

You can see it produces the Reflectivity color and Edge Tint color that you would normally input in an artistic-driven metal shader. But this is from exact measured values and with correct math so the way the colors blend towards the edge is more accurate than using an artistic metal shader with hacked (usually just adjusted for the base reflectance) fresnel node (which in Cycles gives dielectric reflectance response curve).

Connect this into Glossy shader color. The shader should have 0 roughness to be correct.


[UPDATE]: As roughness increases, rays have higher probability to hit the surface dead-on as in center of the sphere. When roughness reaches 1, the whole sphere is shaded with the reflectivity color:

enter image description here

Here is an upgraded PBR version with roughness all incorporated into one group:

enter image description here

Node group guts:

enter image description here

Blend file:

Now this approach taking measured N and K values has GPU and roughness support - two biggest downfalls removed - which imho puts it on par with PBR artistic-driven shader setups:

  • artistic approach with reflectance and edge-tint color input has ease of adjustment benefit (you can also find recommended/measured color values for metals online).
  • measured N and K values approach gives better and more accurate reflectance behaviour (but still approximated in non spectral renderers).
$\endgroup$
  • $\begingroup$ +1 however, if you add an explanation about how this is better than other solutions, you would add a lot more depth to your answer. $\endgroup$ – JakeD Mar 20 '17 at 12:36
  • $\begingroup$ @pycoder Hi, this is just to address the bounty request for non-OSL implementation of the OSL method (that I assume works) - so it is only better by not requiring OSL. Personally I use artistic driven PBR shaders so I just hope this will be useful for someone. $\endgroup$ – Jaroslav Jerryno Novotny Mar 20 '17 at 12:47
  • $\begingroup$ Crazy! Took me a while to understand the math behind the setup, yummy... Many thanks @Jerryno. Out of curiosity, how you would setup e.g. chromium as PBR shader? Do you really think accuracy, IOR and stuff doesn't matter down the line? $\endgroup$ – brockmann Mar 20 '17 at 18:37
  • $\begingroup$ @brockmann My earlier solution uses an OSL shader, but it also shows how to properly set it up with values from, say, refractiveindex.info. The process should be exactly the same. $\endgroup$ – Scott Milner Mar 20 '17 at 19:40
  • $\begingroup$ @brockmann The math is just copied from the OSL script, which is copied from Maya cmds code: forums.odforce.net/topic/… :) The usage is same like Scott wrote, you just plug the color into glossy shader. I'll add bit more notes into the answer. $\endgroup$ – Jaroslav Jerryno Novotny Mar 20 '17 at 20:06
7
$\begingroup$

Old Answer: (revised one below)

The number you are looking for is just the Refractive Index further up on the site: Edit: Since this is a conductive material, the Reflectance value is actually the correct value for a dielectric approximation of a conductive material.

enter image description here

^^^ not correct!

As long as the material you are creating is dielectric, just plug this into a Fresnel node, and you should be good to go. Custom RGB Curves are not physically accurate and will not give you what you want. What it looks like:

enter image description here enter image description here

Note: I have seen tutorials that say that Blender's Fresnel node isn't accurate, and that you have to do various things to the normal input to make it more physically accurate (Edit: as Ibalazscs said, this is only when taking into account roughness, and this method is also correct.). I tested this by creating a group of Math nodes with the Fresnel Equations and comparing it to the Fresnel node. They look exactly the same:

enter image description here

NodeGroup:

enter image description here


Revised Answer

The above answer was just for dielectric materials. The question was asking for conductive (metallic) materials. After looking through some code and reading this page from the Developer site, I found that Blender only has partial support for conductive Fresnel. It appears that it was going to become part of the Cycles node system, and then was abandoned. The developers did include it, though, as an OSL shader template, so it can still be used.

To use it, first enable Open Shading Language under the Render settings. (Note: Using OSL for this slowed down my render times a bit.)

enter image description here

Next, open up a Text Editor. Click on Templates > Open Shading Language > Fresnel Conductive.

enter image description here

In the Node Editor, add a Script node (Shift + A > Script > Script). Select the text file you just created (fresnel_conductive.osl).

Now, here's the tricky part. The IOR of a conductive material is a complex number in the form n+ik. Not only that, but it changes depending on the wavelength of the light hitting it, so the IOR is different for different colors of light. This OSL script takes only three IORs and interpolates the rest with a spline curve. It is still a good approximation, though. Onward!

Using a database like refractiveindex.info, find the complex ior for three different wavelengths of light, probably red, green, and blue, or about 0.68µm, 0.55µm, and 0.40µm, respectively. Plug the red, green, and blue values into the red, green, and blue slots of n and k on the node. My final node setup (using the Chromium values) looked like this:

enter image description here

Although this is an imperfect workaround, there is hope! There is an open developer page on a Metallic BSDF that would do all of this better and just built in.

Sorry that the initial answer wasn't what you were looking for. Hope that this helps more.

$\endgroup$
  • 1
    $\begingroup$ That's the hobbyist approach. First of all the question is about metal (non-dielectric). Also I doubt that your statement "Custom RGB Curves are not physically accurate..." is true. IOR is an overall value, as you can see in the diagram I posted, each reflection curve is different. Check out vray masterclass and you'll see adjusting the cuves individually is a common process. Thank you anyway. $\endgroup$ – brockmann Jan 19 '17 at 9:47
  • 3
    $\begingroup$ Blender's Fresnel node isn't accurate in the sense that it does not take roughness into account. It is accurate for theoretical, perfectly smooth surfaces. $\endgroup$ – lbalazscs Jan 19 '17 at 10:53
  • 3
    $\begingroup$ @brockmann "each reflection curve is different" - are you aware that the red, green, blue curves in your diagram are not for red, green, blue light, but for different polarizations, and in majority of cases only the green (unpolarized) curve is relevant? Do you want to keep track of light polarization? $\endgroup$ – lbalazscs Jan 19 '17 at 10:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.