POV-Ray : Newsgroups : povray.advanced-users : How does POV-Ray handle IORs between two interfacing surfaces? Server Time
1 Nov 2024 01:23:01 EDT (-0400)
  How does POV-Ray handle IORs between two interfacing surfaces? (Message 1 to 10 of 10)  
From: Retsam
Subject: How does POV-Ray handle IORs between two interfacing surfaces?
Date: 2 Apr 2003 15:05:04
Message: <web.3e8b41bd8073fdf12a3ff2e70@news.povray.org>
Maybe someone with more in-depth knowledge of the source code for POV-Ray
can field this one.

I've been looking at the code, trying to figure out how POV-Ray handles a
refracted ray as it passes from one object to another, such as from a glass
bottle to the water in the bottle.

Assuming that I have a "water" object whose surface "exactly" matches the
inside surface of the glass, I would expect the ray to transition from the
IOR of the glass to the IOR of the water.

But from what I can tell from the source code, something bizarre will
happen.

The ray will first enter the glass from the outside, going from ior 1 to ior
1.57, for example.  Then, in the Trace function, depending on whether
Best_Intersection is the glass ending or the water starting, you will get
one of two outcomes.  If it's the glass ending, the ray will go from ior
1.57 to 1.0.  Then the next Trace intersection will be with the water,
going from ior 1.0 to ior 1.33.  Definitely wrong, as you will get TIR at
angles as small as about 40 degrees, instead of the larger 57 degrees or so
they should start at.

On the other hand, if the first intersection is with the water, it will go
from ior 1.57 to 1.33 (the ior at the interface = 1.57/1.33), then as it
leaves the glass, it will go from ior 1.57 to 1.33 again, sort of.  That
is, it will refract twice using the same relative iors.

Am I reading something wrong here?  I've been looking for code that handles
the coincident surfaces, but I cannot find it.

The only way I can see to get a realistic glass/water transition is to have
the glass be solid and just put water inside it.  But what about at the
surface of the water.  There would still be two transitions there.  When
leaving the water, you would get either water-glass and glass-air, or
glass-water and water-air, depending on whether it hit the end of the water
first or the end of the glass first.  Vice-versa for entering the water
from the surface.


Post a reply to this message

From: Gwen & Emory Stagmer
Subject: Re: How does POV-Ray handle IORs between two interfacing surfaces?
Date: 2 Apr 2003 22:10:41
Message: <3E8BA51F.B3457614@comcast.net>
You're absolutely right, that's the way it works.  It's a well known 
problem with all ray-tracers, not just POV.  One solution is to make
single-surface solids with meshs or triangles.  Since these have no
thickness, they have no second side for the ray to exit against and
transition from your 'glass' to 'air' before going to the 'water'.  
It's messy to create and still have all the solids you want, but
that's the best solution I know of...

Emory

Retsam wrote:
> 
> Maybe someone with more in-depth knowledge of the source code for POV-Ray
> can field this one.
> 
> I've been looking at the code, trying to figure out how POV-Ray handles a
> refracted ray as it passes from one object to another, such as from a glass
> bottle to the water in the bottle.
> 
> Assuming that I have a "water" object whose surface "exactly" matches the
> inside surface of the glass, I would expect the ray to transition from the
> IOR of the glass to the IOR of the water.
> 
> But from what I can tell from the source code, something bizarre will
> happen.
> 
> The ray will first enter the glass from the outside, going from ior 1 to ior
> 1.57, for example.  Then, in the Trace function, depending on whether
> Best_Intersection is the glass ending or the water starting, you will get
> one of two outcomes.  If it's the glass ending, the ray will go from ior
> 1.57 to 1.0.  Then the next Trace intersection will be with the water,
> going from ior 1.0 to ior 1.33.  Definitely wrong, as you will get TIR at
> angles as small as about 40 degrees, instead of the larger 57 degrees or so
> they should start at.
> 
> On the other hand, if the first intersection is with the water, it will go
> from ior 1.57 to 1.33 (the ior at the interface = 1.57/1.33), then as it
> leaves the glass, it will go from ior 1.57 to 1.33 again, sort of.  That
> is, it will refract twice using the same relative iors.
> 
> Am I reading something wrong here?  I've been looking for code that handles
> the coincident surfaces, but I cannot find it.
> 
> The only way I can see to get a realistic glass/water transition is to have
> the glass be solid and just put water inside it.  But what about at the
> surface of the water.  There would still be two transitions there.  When
> leaving the water, you would get either water-glass and glass-air, or
> glass-water and water-air, depending on whether it hit the end of the water
> first or the end of the glass first.  Vice-versa for entering the water
> from the surface.


Post a reply to this message

From: Retsam
Subject: Re: How does POV-Ray handle IORs between two interfacing surfaces?
Date: 2 Apr 2003 23:10:03
Message: <web.3e8bb334eee3489b34dff4bb0@news.povray.org>
Gwen & Emory Stagmer wrote:
>You're absolutely right, that's the way it works.  It's a well known
>problem with all ray-tracers, not just POV.  One solution is to make
>single-surface solids with meshs or triangles.  Since these have no
>thickness, they have no second side for the ray to exit against and
>transition from your 'glass' to 'air' before going to the 'water'.
>It's messy to create and still have all the solids you want, but
>that's the best solution I know of...
>
>Emory
>

I thought of that, but I couldn't figure out how to make it work in both
directions.  Since a mesh object has no inside, how can I make it so that
light travelling the other way will enter "glass" when it exits the water?
Since the IOR engine tracks what it is "inside" of, when it leaves the
water, it will hit air, and when it reaches the other side of the glass, it
will get confused, because it wasn't inside the glass to begin with.

Is there a way to make surfaces that can be intersected from one side, but
not another?  You know, so that you can make the glass and the water on the
glass/water interface one-way surfaces (i.e., you can go from the water to
glass and glass to water)?  In other words, it would only intersect one of
the two surfaces, depending on which direction it's going?


Post a reply to this message

From: Christopher James Huff
Subject: Re: How does POV-Ray handle IORs between two interfacing surfaces?
Date: 2 Apr 2003 23:15:22
Message: <cjameshuff-5F81E5.23155702042003@netplex.aussie.org>
In article <web.3e8b41bd8073fdf12a3ff2e70@news.povray.org>,
 "Retsam" <nomail@nomail> wrote:

> I've been looking at the code, trying to figure out how POV-Ray handles a
> refracted ray as it passes from one object to another, such as from a glass
> bottle to the water in the bottle.

The explanation is fairly complex, and has been covered in-depth several 
times. Basically, you should overlap the objects slightly, just enough 
to avoid precision errors.


> Assuming that I have a "water" object whose surface "exactly" matches the
> inside surface of the glass, I would expect the ray to transition from the
> IOR of the glass to the IOR of the water.

No. Because of precision errors, the objects will either overlap, have a 
gap between them, or the surface of one will be missed entirely. You 
need to either overlap or separate them, based on the desired results. 
As long as the objects are well-behaved, with no holes in the surface or 
internal surfaces, it will work.


> The ray will first enter the glass from the outside, going from ior 1 to ior
> 1.57, for example.  Then, in the Trace function, depending on whether
> Best_Intersection is the glass ending or the water starting, you will get
> one of two outcomes.  If it's the glass ending, the ray will go from ior
> 1.57 to 1.0.  Then the next Trace intersection will be with the water,
> going from ior 1.0 to ior 1.33.  Definitely wrong, as you will get TIR at
> angles as small as about 40 degrees, instead of the larger 57 degrees or so
> they should start at.

Not wrong, entirely correct. If you hit the glass first, there is an air 
gap between the glass and the water. This doesn't usually happen with 
glass and water in reality, it only happens here because you set things 
up wrong. However, if you get a piece of glass dirty and sufficiently 
water-repellent, with some kind of oil for example, it will keep a film 
of air which has a silvery appearance.


> On the other hand, if the first intersection is with the water, it will go
> from ior 1.57 to 1.33 (the ior at the interface = 1.57/1.33), then as it
> leaves the glass, it will go from ior 1.57 to 1.33 again, sort of.  That
> is, it will refract twice using the same relative iors.

No, the second glass refraction is ignored. POV maintains a list with 
the objects it is currently "inside", which lets it figure out when 
refraction should be done.

At first, the list is empty: |>

Ray hits glass, which is not in list. Refraction takes place 
(air-glass), glass is added to list. list: |glass>

Ray hits water, which is not in list. Refraction takes place 
(glass-water), water is added to list. list: |glass, water>

Ray hits glass again, which is now in list, but not most recent. 
Refraction is ignored because it was already done for this object, glass 
is removed from list. |water>

For simplicity, say the ray now exits directly into air.
Ray hits water again, which is in list and most recent. Refraction is 
done again (water-air), water is removed from list. |>


> Am I reading something wrong here?  I've been looking for code that handles
> the coincident surfaces, but I cannot find it.

Because it doesn't exist. That's why you aren't supposed to use 
coincident surfaces.

-- 
Christopher James Huff <cja### [at] earthlinknet>
http://home.earthlink.net/~cjameshuff/
POV-Ray TAG: chr### [at] tagpovrayorg
http://tag.povray.org/


Post a reply to this message

From: Christopher James Huff
Subject: Re: How does POV-Ray handle IORs between two interfacing surfaces?
Date: 2 Apr 2003 23:20:33
Message: <cjameshuff-0FB7E4.23211002042003@netplex.aussie.org>
In article <3E8BA51F.B3457614@comcast.net>,
 Gwen & Emory Stagmer <emo### [at] comcastnet> wrote:

> You're absolutely right, that's the way it works.  It's a well known 
> problem with all ray-tracers, not just POV.  One solution is to make
> single-surface solids with meshs or triangles.  Since these have no
> thickness, they have no second side for the ray to exit against and
> transition from your 'glass' to 'air' before going to the 'water'.  
> It's messy to create and still have all the solids you want, but
> that's the best solution I know of...

That will not work properly. Besides being unnecessarily difficult, your 
solution gives very incorrect results. The exiting surface is necessary 
for POV to account for exiting the shape, if it hits a glass object, it 
considers itself inside that object until it hits it again. The correct 
solution is to just overlap the shapes.

-- 
Christopher James Huff <cja### [at] earthlinknet>
http://home.earthlink.net/~cjameshuff/
POV-Ray TAG: chr### [at] tagpovrayorg
http://tag.povray.org/


Post a reply to this message

From: Warp
Subject: Re: How does POV-Ray handle IORs between two interfacing surfaces?
Date: 3 Apr 2003 05:26:20
Message: <3e8c0c4c@news.povray.org>
Retsam <nomail@nomail> wrote:
> Since a mesh object has no inside, how can I make it so that
> light travelling the other way will enter "glass" when it exits the water?

  IOR calculations don't need solid objects.
  You can perfectly make a glass object which is actually a mesh or made of
bicubic patches.
  Naturally the IOR calculation routine expects the surface to be well-behaved
and closed, but you shouldn't expect a non-closed mesh to work ok anyways.

-- 
plane{-x+y,-1pigment{bozo color_map{[0rgb x][1rgb x+y]}turbulence 1}}
sphere{0,2pigment{rgbt 1}interior{media{emission 1density{spherical
density_map{[0rgb 0][.5rgb<1,.5>][1rgb 1]}turbulence.9}}}scale
<1,1,3>hollow}text{ttf"timrom""Warp".1,0translate<-1,-.1,2>}//  - Warp -


Post a reply to this message

From: Christopher James Huff
Subject: Re: How does POV-Ray handle IORs between two interfacing surfaces?
Date: 3 Apr 2003 09:29:22
Message: <cjameshuff-7675EE.09295903042003@netplex.aussie.org>
In article <web.3e8bb334eee3489b34dff4bb0@news.povray.org>,
 "Retsam" <nomail@nomail> wrote:

> I thought of that, but I couldn't figure out how to make it work in both
> directions.  Since a mesh object has no inside, how can I make it so that
> light travelling the other way will enter "glass" when it exits the water?

Use a closed mesh so it hits the glass again. Or don't use a mesh.
And solidness of the object doesn't matter, as long as it is closed.


> Since the IOR engine tracks what it is "inside" of, when it leaves the
> water, it will hit air, and when it reaches the other side of the glass, it
> will get confused, because it wasn't inside the glass to begin with.

This tracking is exactly why using a mesh is unnecessary.


> Is there a way to make surfaces that can be intersected from one side, but
> not another?  You know, so that you can make the glass and the water on the
> glass/water interface one-way surfaces (i.e., you can go from the water to
> glass and glass to water)?  In other words, it would only intersect one of
> the two surfaces, depending on which direction it's going?

The closest thing is inside_texture, which isn't quite what you 
describe. For one thing, it won't let you change ior. There is no 
feature that does exactly what you describe.

-- 
Christopher James Huff <cja### [at] earthlinknet>
http://home.earthlink.net/~cjameshuff/
POV-Ray TAG: chr### [at] tagpovrayorg
http://tag.povray.org/


Post a reply to this message

From: Retsam
Subject: Re: How does POV-Ray handle IORs between two interfacing surfaces?
Date: 5 Apr 2003 00:15:03
Message: <web.3e8e663aeee3489b34dff4bb0@news.povray.org>
Christopher James Huff wrote:

>
>> On the other hand, if the first intersection is with the water, it will go
>> from ior 1.57 to 1.33 (the ior at the interface = 1.57/1.33), then as it
>> leaves the glass, it will go from ior 1.57 to 1.33 again, sort of.  That
>> is, it will refract twice using the same relative iors.
>
>No, the second glass refraction is ignored. POV maintains a list with
>the objects it is currently "inside", which lets it figure out when
>refraction should be done.
>
>At first, the list is empty: |>
>
>Ray hits glass, which is not in list. Refraction takes place
>(air-glass), glass is added to list. list: |glass>
>
>Ray hits water, which is not in list. Refraction takes place
>(glass-water), water is added to list. list: |glass, water>
>
>Ray hits glass again, which is now in list, but not most recent.
>Refraction is ignored because it was already done for this object, glass
>is removed from list. |water>
>
>For simplicity, say the ray now exits directly into air.
>Ray hits water again, which is in list and most recent. Refraction is
>done again (water-air), water is removed from list. |>

I know that's probably what's intended, but I'm just looking at the code.
To wit:

  if (Ray->Index == -1)
      ....
  }
  else
  {
    /* The ray is currently inside an object. */
    if ((nr = Interior_In_Ray_Container(&NRay, Interior)) >= 0)
    {
      /* The ray is leaving the current object. */
      Ray_Exit(&NRay, nr);
            if (NRay.Index == -1)
      {
        /* The ray is leaving into the atmosphere. */
           .......
      }
      else
      {
        /* The ray is leaving into another object. */
        ior = Interior->IOR / NRay.Interiors[NRay.Index]->IOR;
             ....

It looks to me like this happens.  The ray enters the glass, ior 1:1.57.  We
all agree so far.  Next, if I have the water go slightly inside the glass,
then there will be a water hit, and refraction at ior 1.57:1.33.  Again, we
all agree so far.

Now, the Trace function is called again.  There's a hit, this time as the
ray exits the glass (still in the water).

Looking at the code above, this is what I see.  Ray->Index != -1, so we go
to the else.

The Interior_In_Ray_Container function is passed the current ray, and the
Interior we're checking.  Correct me if I'm wrong, but Interior in this
comparison is the container that was just intersected, right?  If I'm
wrong, then what is Interior?

But assuming Interior is the glass, the function will return the index to
the glass (which is removed from the list), and nr will be greater than or
equal to 0.  Note the comment, the ray is leaving the current object, i.e.
the glass.

Now, NRay.Index should be non-negative after the Ray_Exit() call, since
we're still in the water.  So we move into the next else block, which is
commented as "The ray is leaving into another object", i.e. the water.
Note that it does a 1.57:1.33 transition AGAIN.

Now, I haven't stepped through the code, so I may be missing something.  But
what is it?


Post a reply to this message

From: Retsam
Subject: Re: How does POV-Ray handle IORs between two interfacing surfaces?
Date: 6 Apr 2003 19:05:03
Message: <web.3e90b142eee3489b34dff4bb0@news.povray.org>
>Christopher James Huff wrote:
>>No, the second glass refraction is ignored. POV maintains a list with
>>the objects it is currently "inside", which lets it figure out when
>>refraction should be done.
>>
>I know that's probably what's intended, but I'm just looking at the code.

I ran a test to confirm my suspicion.  Rays were refracted twice at an ior
of 1.57:1.33, once on entering the water, and once on leaving the glass
(into the water).  I did the test with POV-Ray 3.5 for Windows (Version
3.5.icl.win32)

If it really is supposed to work the way you described, where it only
refracts when leaving a surface if it's the last surface entered, then we
should make the following code change:

      /* The ray is leaving the current object. */
      Ray_Exit(&NRay, nr);
            if (NRay.Index == -1)
      {
        /* The ray is leaving into the atmosphere. */
           .......
      }
      else if (NRay.Index+1 == nr)   <------ this line was changed.
      {

I could be off by one.  But as I read it, NRay.Index should equal nr if the
ray is leaving the last object entered.  After the call to Ray_Exit,
NRay.Index will be reduced by one: hence the "+1" in the if statement.

I apologize if this post appears twice.  I posted a similar response last
night, and it hasn't shown up yet nearly a day later.

By the way, do the developer's read messages in here?  Who would I talk to
about making this code change, if it is the way it should be handled (the
documentation doesn't really describe the way it's supposed to work in
tricky scenarios like this)?


Post a reply to this message

From: Gwen & Emory Stagmer
Subject: Re: How does POV-Ray handle IORs between two interfacing surfaces?
Date: 6 Apr 2003 23:44:33
Message: <3E90F30E.6A0D0CD5@comcast.net>
Retsam,
    Christopher James Huff is on a TAG team and I'm sure it will get
noted and checked...

Emory

Retsam wrote:
> 
> >Christopher James Huff wrote:
> >>No, the second glass refraction is ignored. POV maintains a list with
> >>the objects it is currently "inside", which lets it figure out when
> >>refraction should be done.
> >>
> >I know that's probably what's intended, but I'm just looking at the code.
> 
> I ran a test to confirm my suspicion.  Rays were refracted twice at an ior
> of 1.57:1.33, once on entering the water, and once on leaving the glass
> (into the water).  I did the test with POV-Ray 3.5 for Windows (Version
> 3.5.icl.win32)
> 
> If it really is supposed to work the way you described, where it only
> refracts when leaving a surface if it's the last surface entered, then we
> should make the following code change:
> 
>       /* The ray is leaving the current object. */
>       Ray_Exit(&NRay, nr);
>             if (NRay.Index == -1)
>       {
>         /* The ray is leaving into the atmosphere. */
>            .......
>       }
>       else if (NRay.Index+1 == nr)   <------ this line was changed.
>       {
> 
> I could be off by one.  But as I read it, NRay.Index should equal nr if the
> ray is leaving the last object entered.  After the call to Ray_Exit,
> NRay.Index will be reduced by one: hence the "+1" in the if statement.
> 
> I apologize if this post appears twice.  I posted a similar response last
> night, and it hasn't shown up yet nearly a day later.
> 
> By the way, do the developer's read messages in here?  Who would I talk to
> about making this code change, if it is the way it should be handled (the
> documentation doesn't really describe the way it's supposed to work in
> tricky scenarios like this)?


Post a reply to this message

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.