Micro/angle dependent Roughness & Iridescence

I have created this thread to discuss and further develop the “micro roughness” effect - whereby the apparent roughness of a semi-glossy material falls off at grazing angles - thereby making reflections sharper.

I have already created a node group to simulate this effect and a BDRF solution to this effect has also been described in a siggraph paper - both linked below.

These two images show an arc vis scene from Blendswap both without (top image) and with (bottom image) the effect active. Credit for the scene goes to Blendswap user NewSee2l035 - but I had to adapt the materials for Cycles.



I have also created a video to show this effect based on real experiments done by MartinZ over in the Disney shader thread

One other advantage of this effect seems to be that it solves the Fresnel Halo effect at high roughness values without actually having to change the Fresnel parameters. The halo seems to disappear as a natural consequence of having angle dependent roughness.


I guess the aim is to try to come up with a node based solution that most accurately mimics this effect - with the hope that Cycles may one day incorporate this in it’s Glossy BDRF or Principled shader.

6 Likes

Ok Moony, you and MartinZ eventually convinced me. :slight_smile:
Videos and papers helped a lot.
So now I’m again getting hands dirty with my “default” shader, and, unless someone comes with proper math I propose this node setup:

Instead of eyeballing with curves and arbitrary adjustements, what I did is use fresnel (Schlick’s approximation) to drive the roughness sharpening. Just guessing here: I thought that maybe the same nature’s law apply here as well…
Reproducing a hallway like in Thea video gives me a nice result though.

1 Like

Another test:

I think it would be logical to avoid making assumptions about any rules that this effect follows. If you do image search on Google for some materials with added keywords like ‘microscopic’, ‘microscope’ or something like that, you will find there are really a lot of different forms a structure of any surface can have. If you think about it if there are peaks on the surface that are more flat, the more at an angle you view them the more you see only the peaks, therefore you see only the flat surface that is reflective. How flat the peaks be might be might influence how blurry the sharpest reflection will be. But there can be a lot of different possibilities with 3-dimentional structure of a surface… so the effect can start at any angle and be strongest at any other angle as well and its strength can vary. I think its best to look at real world examples, photographs and observe how the effect behaves. I think it is best to have shader’s roughness easily controllable along all the range of camera facing angles. I would therefore use curves or color ramp instead of some mathematical formulas. I will share my workflow in approximating this effect from photographs the moment I get some spare time to do it.

Hmm - i’m not sure, the falloff seems to occur at far to shallow an angle using the Fresnel method.

The first render is my node setup with a roughness value of 0.2. The second is yours with the same roughness value. The third shot shows that the angle the camera is viewing from is very shallow indeed (probably not to dissimilar to the angle my iPhone test video was at.)




The text is far more legible over a broader area using my node setup - which is closer to what I observed. The reflections using the fresnel method are only really sharp right at the very edge of the text/floor interface.

I personally do think that a maths based approach is the way to go though - since the input parameters are far easier to control and make visible to the users. Curves whilst useful are just a bit too fiddly if they have to be modified on a per material basis.

With math nodes - it’s easy to say X, Y and Z values will approximate an iPhone, whilst A, B and C values will approximate satin paint.

That’s why I have set my nodes up the way I have. I found two curves I thought worked well at the extremes - then just exposed a single ‘softness’ parameter to the user that allows them to transition from one curve to the other - without actually having to touch the curves themselves.

Right. I just think I’ll be good with this easy approximation that at least lets me have the effect in place. Fine tuning per-material seems overkilling to me. I’ll take for good a single slider, as I take for good 1.5 fresnel for all dielectric materials as many of us do now with PBR. :wink:
This kind of simplification doesn’t have great impact on final renders*, at least not greater than the impact it can have on workflow.

  • I mean, often tweaking ‘bias’ option like bounces number, fake caustics etc, doesn’t give a result which you can look at and label “unrealistic”.

I’ll be experimenting a little bit more. It could just be the matter of reducing the power from 5 to 4 or less

I believe something important will be overlooked.
Months ago I’ve once read the microfacet roughness, in the cycles glossy shader,is just a mix blend slider , from glossy to diffuse.
As well as a diffuse node and glossy node in a mix shader.

In the thea tutorial video, however, is clearly to be seen and described, the microsurface in micro mm is indicated as a large input.also width and height in mm / 1000

Moreover was shown in the render, the basic material 0% glossy leave, and additionally only the size of the microsurface can adjust.

Later one could also see how a kind of wave effect was added on the surface.

And I believe this is the point.

To simulate that I think you could have a noise texture or wave texture (whatever you want for a surface) and this with scale for the wide, and brightness contrast for the height control.

This should now be linked as a bump or displacment to have the desired microsurface effect.

Hope this was understandably written what I wanted to say.

I think I understand - and I did such a test on the Disney thread - adding a very small bump map to simulate the microsurface (see below). This would be an ideal scenario - since all you would need to do to simulate any surface is plug an appropriate bump or normal map into a perfectly glossy shader.

The problem is - Blender doesn’t handle textures with a very small scale very well at all and you can start to get all sorts of image artifacts if you scale the texture down too much.

One thing the test did show however is that (in spite of the image artifacts) simulating ‘physically’ it in this way does give closer results to reality and to my node group - than just using Fresnel, so I guess it kinda validates the concept.


I don’t think it makes much sense in simulating the effect physically in Cycles. Cycles is not spectral renderer nor it was ever meant to be physically correct - there will be little benefit in this. I think the result of the effect is what should be more important to us and the height and width of the micro bumps can be ignored. I think these are not the only factors that would impact the physical effect anyway - the distribution and shape of microscopic bumps on the surface should also matter. Thea also simplifies stuff a lot in this case. I think it is just not so practical to look at this from the physical point of view keeping in mind the lack of scientific research on the subject and lack of measured data decisions could be based on. If the physical correctness is skipped and we try to match the result of the effect directly a lot of unknown variables become irrelevant and the effect will be recreated more accurately at this point. Please correct me if I am wrong, but I don’t think we could reach a solution that would incorporate this effect correctly into the calculation of global illumination with nodes anyway. Let’s not over do it. I think it does make sense to adjust the effect per material though. From what I have observed as far it varies greatly from one material to another.

Indeed - there are so many variables to consider that I don’t think we could ever represent it in a ‘physically accurate’ manner (just some of those I can think of are listed below). Even the paper I linked to only treated this effect in a very generic way looking at a few materials under specific lighting conditions - and then trying to get an overall distribution function that fit with those observations.

  • Height
  • Width
  • Size uniformity
  • Shape
  • Orientation
  • Material
  • Surface coating/oxidation
  • Wavelength of light

I guess as a starting point - just the acknowledgement that this effect does occur in the real world - and the fact that cycles doesn’t currently consider it - is a start. It allows us to consider ways of simulating it.

Just putting together a generalised node that allows some control over roughness falloff will lead to a huge leap in realism - even if isn’t exactly physically correct. Getting to 70-80 or 90% accurate may be enough to start with.

Cycles is improving all the time and who knows what effects will be introduced in the future. Just look at the additional options to SSS, Anisotropic and Glossy nodes we have got since those nodes were first introduced. The lack of these didn’t stop useful or realistic work being performed - but the introduction of these new functions just made it easier to make things look ‘more real’.

Many effects in cycles have to be ‘fudged’ at the moment (dispersion, iridescence etc), but with pretty good results - so it is with micro roughness at the moment.

Just playing around with my nodes again (that sounds rude doesn’t it :D)

I noticed that the RGB curve version has actually broken the Fresnel halo fix :frowning:

I have created a new node setup that should hopefully readdress the issue. Instead of passing the Facing value into two RGB curves and mixing them to control the softness parameter - I now mix between two facing values directly (0.7 and 0.3) and omit the RGB curves (TBH I wasnt really happy using them anyway)

All three images below have a roughness value of 1. The first image has softness = 0.0, the second has softness set at 0.5 and the final image has micro roughness turned off - as a comparison to show the Fresnel Halo.




Even at very high softness values (i.e. 1) - the halo is greatly diminished, and that which does remain is smoothed out and graded so that it looks less obtrusive and more like natural lighting as opposed to an artifact. The halo appears completely eliminated up to a softness value of around 0.5.

This is my new node group


What’s the use of having two Layer weight and a slider to mix them? Just use one and that softness value will be the factor :wink:

I find this to be the most complete way to control the effect also the most intuitive and visual:


I noticed one more interesting effect accidentally - if you take sin() of the angle between incoming and normal, you get a gradient matching the color ramp on screen space. That might be even more visual and intuitive way to adjust things. I am thinking of actual angles so the previous linear angle and falloff curve will work best for me now, but this might also be very convenient.


Yep - already made that tweak late last night :smiley:

With regards to your node setup above - a couple of thoughts:

  1. When I tried it your top node - the roughness falloff is the opposite way round to what I expected (i.e. goes more rough at glancing angles). I had to insert an “invert” node after the colour ramp to get the fall off to behave correctly.

  2. Instead of the ramp - which can be difficult to control and expose to the users - could you use a gamma node instead? That allows you to apply a gamma curve to change the falloff behaviour - but the user only needs to change a single number.

  3. I also think a softness parameter would be a good idea. Sometimes the sharpness of the reflection at glancing angles can be too distracting and we need a way to tone it down. In my node setup - the softness factor effectively limits the minimum roughness. Without this - the roughness at glancing angles always tends to zero.

I have modified your node setup to add a softness parameter and change the RGB curve for a gamma curve. Note that the screenshot below shows the softness multiplier set to 0.1. After some playing, I upped it to 0.2 for the tests below.


I have done a comparison between your modified node setup (with added softness and gamma control :D) and my last version. In both cases, roughness and softness are cranked up to the maximum. Personally I think yours (the bottom image) is much better and looks more natural.



One thing I did notice about your node setup though - and i’m not sure if it’s something to do with the fact that you are using the tangent space bump node - but it doesn’t appear to play well with micro displacement (at least in this scene)

In the hall test scene - I have micro displacement on the floor to give the tiles some depth. When micro displacement is active, the floor using your node setup appears completely glossy and doesn’t show any micro roughness falloff. If I turn micro displacement off, the micro roughness falloff works as expected.



Although - I have tried recreating the problem in another scene and can’t get it to manifest. I could fix it however by plugging the normal slot of the geometry node into the dot product - instead of the bump node.

Sorry - forum error resulted in multiple posts (mods can you delete?)

Sorry - forum error resulted in multiple posts (mods can you delete?)

Sorry - forum error resulted in multiple posts (mods can you delete?)

Sorry - forum error resulted in multiple posts (mods can you delete?)