Cycles - why the refraction index is limited to >=1?

IMHO the least computationally expensive method of rendering situations like a liquid in a glass is avoiding double surfaces.
In other words - one surface defining air-glass and one for glass-water transition instead of doubling as glass-air/air-water. This should avoid the artifact when a bottle has a clear glass contour around it’s colored content and make render faster.

To achieve that, the surface between glass and water should step down in refraction value from 1.55 of glass to 1.33 of water, as light passes to less dense material, thus making surface refraction value less than 1. About 0.88 if I’m not missing something.

The problem is refraction value of glass shader in Cycles is limited to >=1. Why so?

Edit: I was able to achieve possibly the same as desired effect by making water with right refraction (1.55-1.33+1), but normals pointing inside. Though it might not do any good if material will have some diffuse component percentage.

I believe OpenShadingLanguage limit this…
To fix this we need modify only few lines of code in OSL.

I really dislike this limitation

If you have backfaces - you must invert IOR to get correct result
1/1.33 = 0.751

This is not possible - and IOR fail

I posted this to bugtracker - but it was closed… :frowning:

not a bug - it is a feature (without giving us options to “fix” that feature)
we need double faces or lower IOR than 1.0

You seem to be complaining about a little bit different problem, but yes, the solution would be the same.

The bottle on the left shows example of double faced mesh. Notice the edge of clear glass on the contour.
On the right I tried to simulate <1 IOR on single surface transition by inverting normals of liquid inside. Kinda worked, but very likely introduced other errors.
Presumably real :slight_smile: bottle for reference (no clear glass edge around):

First off IOR is a ratio between incident and outgoing light into the transparent material. They are not simple constants. So how did you get IOR of less then one?

Secondly I don’t know how Blender calculates two objects with different IOR that is intersecting each other. Yes the artifact is there, but this may be caused by faces with different IOR touching or crossing each other. And, the calculation is going funny.

If you have two object separated by a space, a bottle and liquid, the surface between the two are going to be reflecting each others surface! It’s a kind of hall of mirrors effect. It is not a simple problem.

Anyway, here is better picture of how it should look between glass / air / liquid interface:

My logic is simple - light passing from less to more dense medium (eg. air-glass) gets refracted - among other effects, it’s path is bent according to index of refraction of this piece of glass compared to refraction of air or vacuum. Where refraction may vary from none at index of 1 and grow in some proportion to index growth.
But when light is passing from dense to a less dense medium (eg. glass-air) it gets refracted back, so now we are talking about index of refraction that should result in an inverse of what previous one did. If the refraction index is any sort of angle multiplier, refraction index of <1 should be logical here.

Sure this (or something alike) is done automatically, based on where normals are pointing, but sometimes this may not be the case, as light is not passing back into air but for example into water, creating a new refraction value of difference between one of glass and water, and as water is less dense, light refraction behavior on enter/exit of water-glass surfaces should be reversed, hence the need to define IOR<1.

Of course (at least for now) this is not a perfect solution for 3D modellers as you cannot animate such liquid because you have to remove inner glass surface where the water begins and shader of water surface is different to one between glass/water, but for a static geometry this should result in much more believable look. Really important for close-ups, packshots etc.

AND I should mention that I have no idea what the real formula looks like, so I might be totally wrong :slight_smile:

First off IOR is a ratio between incident and outgoing light into the transparent material. They are not simple constants. So how did you get IOR of less then one?
you should look at cycles code -> OSL
on backfaces, the IOR is inverted:

float eta = backfacing()? 1.0/f: f;
that means:
if backfacing then eta = 1/f
else eta=f

note that OSL limits value:

float f = max(IOR, 1.0 + 1e-5);
so no lower value than 1 is possible

here is a article about: how to make glas:

Thanks for clarification. So this looks like it is easy to fix?

Thanks, basically that describes the same I was saying above, but without fixing inverted normals problem. IOR<1 would be better as it would allow liquid to have diffuse component too, not only refraction.

Edit: after a few experiments, it seems that Cycles doesn’t care about which way the normals go for diffuse, so inverting normals to get IOR<1 seems to be a viable workaround.