Author Topic: Specular To IOR (OSL)  (Read 1173 times)

2021-02-17, 01:37:11


  • Active Users
  • **
  • Posts: 425
  • ฅ^•ﻌ•^ฅ meow
    • View Profile
Recently I got an email about Unreals new MetaHuman, so I thought I could begin to port all the shaders over to Corona for fun in my spare time.

All this porting made me realize how sick I am of the "offline renderer" bias towards IOR instead of Specular. Back when I was the main Corona exporter coder for Megascans, I made a "SpecularToIORv2.3dl" LUT to handle this problem.
Since then, 3dsMaxs OSL support has evolved, and we can do this stuff in engine.

Specular could be implemented in the new Corona Physical Material in a few minutes. We only need to remap pixel values from Specular to IOR, and everything will work as it is.

Specular = 0.5 is the same as IOR = 1.50
(0.08*Specular )*100 = 4 Reflectivity ----- (if Specular is 0.5)
1/((2/(sqrt((Reflectivity /100))+1))-1) = 1.50 IOR ----- (if Reflectivity is 4)

I've made an OSL that will handle all this stuff for you, but I really hope that we can get a switch in Corona to toggle between IOR/Specular.



1. Epic generates a detailed roughness map from the normal map, using the "Composite Texture" part of a texture file in Unreal Engine 4. If you join the UE4 dev group on GitHub you can see the actual code. (and the Blue fix for ACES, wink, wink)

2. Epic custom paints a custom map with broad stokes, to specify what the base roughness value should be.

3. Epic blends the custom painted controlled roughness map with the "Composite Texture" roughness map.

4. Epic use a Fresnel to control and fade between the painted and generated map.


1. Epic generates a Cavity map and remap it to specular values aka IOR.

I always go for cross polarizing specular maps. Cavity generated maps, and if I don't have anything else. I generate a spec map based on the normal map depth, maybe there are just a few pixels on the Z depth, but it's worth it.


1. Epic has a normal map based on scans

2. Epic use a generated detailed "micro" scan. That kind of looks like your average leather sofa.

3. In our example. Epic use a gradient map, to make a mask that specify where the face detail should be, and where the neck portion should be. Because we want less micro detail bellow the neck.

4. Epic blends the scanned normal map with the Generated "leather sofa" map.

I've always been an advocate for IOR/Specular maps, and this is why!

Only Roughness (Corona Physical Material)

Roughness + IOR (Specular) (Corona Physical Material)

Roughness + IOR (Specular) + Normal

Roughness + IOR (Specular) + Normal + Albedo (Default SSS settings with 2cm)

I've over emphasized the IOR/Specular map in this example with no depth of field, just to show you how important this map is.
« Last Edit: 2021-02-17, 03:55:24 by dubcat »
    _] [__|OO|
   (____|___| / ( ͡° ͜ʖ ͡°) choo choo

2021-02-17, 18:51:57
Reply #1


  • Active Users
  • **
  • Posts: 211
    • View Profile
Very cool dubcat, that MetaHuman software is amazing.  I'm also looking forward to UE 5, that might be a game changer.

2021-02-18, 14:41:08
Reply #2


  • Active Users
  • **
  • Posts: 820
    • View Profile
    • arqrenderz
Is it just me or the images on the post are not loading?

2021-02-18, 14:41:48
Reply #3


  • Corona Team
  • Active Users
  • ****
  • Posts: 3794
    • View Profile

2021-02-23, 16:55:56
Reply #4


  • Active Users
  • **
  • Posts: 1439
    • View Profile
Ive missed these dubcat posts. Nice work!

2021-03-02, 00:31:57
Reply #5


  • Users
  • *
  • Posts: 4
    • View Profile
Hi Dubcat! Great work as usual! Can I ask you a clarification about the use of megascans textures? I am a C4d + Corona user and I'm struggling to undesrtand if i have to use the textures with the embedded color profile or if I have to change it to linear.
Usually I use the maps in this order:

  • AO (multiply) + Albedo
  • Roughness (with the new phisical material of corona 7)
  • Specular map: inside the IOR slot, with a value of 1.79, with a corona color correct shader to apply the LUT Specular To Ior v2
  • Normal map: inside corona normal shader

All the textures with the embedded color profile. Is it correct? What is the right setup?
Thanks for the help!!

2021-05-01, 03:30:06
Reply #6


  • Active Users
  • **
  • Posts: 425
  • ฅ^•ﻌ•^ฅ meow
    • View Profile
I'm also looking forward to UE 5

Me too!

Ive missed these dubcat posts.


Can I ask you a clarification about the use of megascans textures?


Just ask yourself, does this texture contain Color Information or Data Information.

Color Information would be Albedo/Diffuse/Translucency
Data Information would be Normal/Displacement/Roughness/Glossiness/Bump/IOR/Specular

Color Information = Load as sRGB / 2.2 Gamma
Data Information = Load as RGB / Linear / 1.0 Gamma

I've never used Cinema 4D, so I have no idea how they handle stuff.
I force gamma settings no matter what engine I use. In Unreal there is an sRGB switch per texture.

There are two kinds of normal maps. OpenGL and DirectX, the only difference is how they handle the Green channel.
In 3dsMax we have to load Megascans Normal Map as linear/1.0 gamma and then check the "Flip green (Y)" box in CoronaNormal.
I would download a material like "MOSSY STONE FLOOR" on Megascan, if I were testing a new engine. This material has indents in the stones, if these indents protrude, you should flip green.

Displacement map is another story. These maps should be 32bit float. But that is not the case with online stores.

If I scan my face, retopo my face, project all the details, export the difference as a 32bit displacement. I can load that linear map and use 1 displacement strength, and I will get correct minus/plus values, just as they were exported. Basically a 1:1 result.

If I exported the same map as 16 or 8 bit, the only difference is how jagged the edges are. I would have to input what the min/max values should be. We have to remap 0/1 to a new value. Because a 16/8 bit map can not go bellow 0 or above 1. Please just export displacement maps as 32bit. Megascans include the min/max values inside the .json file as cm.

But in the end, if you download textures from a site that has no standards, and they have done some inverse gamma on the albedo, and you load the map properly, it will look like shit. sadge

PS. When are we getting in Corona peepoWide
« Last Edit: 2021-05-01, 04:54:56 by dubcat »
    _] [__|OO|
   (____|___| / ( ͡° ͜ʖ ͡°) choo choo

2021-05-01, 10:39:40
Reply #7


  • Global Moderator
  • Active Users
  • ****
  • Posts: 7016
  • Let's move this topic, shall we?
    • View Profile
    • My Models
PS. When are we getting in Corona peepoWide

Maybe if you'd visit frequently enough, probability wave eventually would collapse to the version of reality where it's already implemented? :]
I'm not Corona Team member. Everything i say, is my personal opinion only.
My Models | My Videos | My Pictures

2021-05-01, 17:25:22
Reply #8


  • Active Users
  • **
  • Posts: 52
    • View Profile
I'm still trying to understand this IOR thing. I hope you guys can give me hand:

1) Why exactly is this IOR map needed and what is the physical phenomenon this map is trying to simulate?

2) Should we use IOR map for skin only or for all materials?

3) Is this method needed when using V-Ray too?

4) How do I get IOR maps when all I have is a diffuse texture?