Blend Swap

Fresnel with Accurate Roughness
by Blend Swap
Last crawled date: 8 years, 2 months ago
Fresnel equations describe how the fraction of light reflected by a surface changes depending on the incident angle. Blender hasFresnelandLayer Weightnodes that can compute this. However, they have two deficiencies:Metals have complex IOR (with the imaginary part also known asextinction coefficient), but both nodes only have one real input. It's impossible to reproduce the true metal Fresnel curve using that.Neither node has any way to adjust the effect for roughness.The second point is actually the most difficult one to resolve. Roughness is mathematically simulated using so calledmicrofacet model, which basically assumes that the surface consists of infinitely small perfectly flat faces, with normals randomly perturbed from the average according to a statistical distribution. The fresnel function represents reflection from a flat surface, and thus should be applied to the microfacet normal being sampled; the practical result of this is that the contribution of the fresnel effect actually depends on incoming light direction.Node shaders don't have any access to that information, so I thought that the best thing you can do is try to emulate the appearance of the microfacet model in uniformly lit environment, where the same amount of light is coming from any direction. Given that the whole thing is an approximation, it is then appropriate to sidestep the first problem by using theSchlick's approximationapproach, which simply lets you choose minimal reflectivity, and interpolates a curve between it and 100%.The file contains the following node groups:Fresnel-Sharp: Implements Schlick's approximation, tweaked to reproduce the 1.45 IOR curve with only 0.6-0.8% error.This group should be basically equivalent in its results to the approach suggested by some tutorials of using a constant IOR, subtracting a second Fresnel node using Incoming as normal, and then scaling the result to the desiredMin Reflectivity.The group inputs and outputs reflectivity values as colors so that it can be easily used for adjusting the specular color of metals. There is no additional cost from this for dielectrics, since the Mix RGB node is the most convenient thing to use internally in any case.Note: This node group is redundant in 2.78, because Cycles is now able to simplify Fresnel-GGX into its exact equivalent if Roughness is constant 0.Fresnel-GGX: Builds on the tweaked approximation, and adds math and correction curves to account for roughness.The group was constructed using reference images rendered by Blenderpatchedto include the Fresnel coefficient (1.45 IOR) into the microfacet code used by the GGX Glossy node, and approximates the result with 1.5-2.5% error.There are also a few immediately usable examples of trivial PBR material groups:GlossySurface-GGX: Wraps another shader, adding colorless fresnel glossy reflection to it using a combination ofFresnel-GGXandGlossy. Intended as a building block for dielectric shaders.Metallic-GGX: CombinesFresnel-GGXandGlossyinto a primitive PBR metal material.Dielectric-GGX: CombinesDiffuseandGlossySurface-GGXinto a simple PBR dielectric.Dielectric-IOR-GGX: Like above, but computes Min Glossy from an IOR input.As a bonus, there's also aHighlightRangeDevgroup, which highlights acceptable and unacceptable deviations of a value from a goal using different colors, and was used in tuning the Fresnel node groups.Latest Change on 2016/09/04, 05:01:44Added the immediately usable examples of PBR material groups, and included part of the above text in the blend file.