POV-Ray : Newsgroups : povray.newusers : Problem merging two isosurfaces Server Time
24 Nov 2024 10:40:39 EST (-0500)
  Problem merging two isosurfaces (Message 1 to 10 of 11)  
Goto Latest 10 Messages Next 1 Messages >>>
From: Mike
Subject: Problem merging two isosurfaces
Date: 9 Oct 2008 14:05:00
Message: <web.48ee4781aaa214c0c9b9f9f00@news.povray.org>
I have been trying to create basically a cube in which the top and bottom face
is a 2D sine wave (egg crate pattern).  I have been able to do this using
isosurface, with some trouble however.  The way I found to do this was to make
one isosurface sine wave pattern contained by a box and then make another one
also contained by a box and flip it over.  My problem is that when I try to
merge the two objects I create, I have tried merge and union I always see a
middle boundary in between them.  The indicies of refraction are matched and I
am using fresnel reflection, so I do not see how or why I am seeing this.  If
anyone has any ideas on how to make this artifact go away that would be very
helpful.  I have posted the code I used to make the object below.

Thanks,
Mike

#declare MixedRegion =
material {
  texture {
     pigment {
        color rgbf<0.3, 0.5, .5,1>
      }

 finish {
        ambient 0.0
        diffuse 0.0
         reflection {
          0.0, 1.0
          fresnel on
        }
        conserve_energy
        specular 0.0
        roughness 0.0
 }
  }
  }


#declare botMixingHalf=
isosurface {
  function {
    ( y-5 + .1*sin(3*6.2832*x)*sin(3*6.2832*z))
  }
  max_gradient 4
  accuracy .0001
  contained_by { box { <-1.8999, 4.5, -1.8999>, <1.8999, 5.1, 1.8999> } }
material { MixedRegion }

     interior {
    ior 1.400
}
 photons{
             target
                refraction on
               reflection on
  }
 rotate 180*z
 translate 8*y
}


#declare topMixingHalf=
isosurface {
  function {
    ( y-4 - .1*sin(3*6.2832*x)*sin(3*6.2832*z))
  }
  max_gradient 4
  accuracy .0001
  contained_by { box { <-1.8999, 3.2, -1.8999>, <1.8999, 4.1, 1.8999> } }

material { MixedRegion }

     interior {
    ior 1.400
}
 photons{
                target
                refraction on
                reflection on
  }
}

#declare Mixingregion=
merge{object{topMixingHalf}
object{botMixingHalf}}

object{Mixingregion}


Post a reply to this message

From: Mike Williams
Subject: Re: Problem merging two isosurfaces
Date: 9 Oct 2008 15:33:30
Message: <ItxNcZC$xl7IFwwZ@econym.demon.co.uk>
Wasn't it Mike who wrote:
>I have been trying to create basically a cube in which the top and bottom face
>is a 2D sine wave (egg crate pattern).  I have been able to do this using
>isosurface, with some trouble however.  The way I found to do this was to make
>one isosurface sine wave pattern contained by a box and then make another one
>also contained by a box and flip it over.  My problem is that when I try to
>merge the two objects I create, I have tried merge and union I always see a
>middle boundary in between them.  The indicies of refraction are matched and I
>am using fresnel reflection, so I do not see how or why I am seeing this.  If
>anyone has any ideas on how to make this artifact go away that would be very
>helpful.  I have posted the code I used to make the object below.

You could do this:

global_settings {max_trace_level 50}

#declare F = function {y-4.5 + .1*sin(3*6.2832*x)*sin(3*6.2832*z)}

#declare WholeThing =
isosurface {
  function { abs(F(x,y,z))-0.5}
  max_gradient 2.1
  accuracy .0001
  contained_by { box { <-1.8999, 3.9, -1.8999>, <1.8999, 5.1, 1.8999> }}
  material { MixedRegion }

  interior {
    ior 1.400
  }
  photons{
    target
    refraction on
    reflection on
  }
}

I'm getting some dark specks. I don't know if that's due to
max_trace_level, or my lighting, or if it's a real effect caused by
small reflections or refractions of shadowed areas. They don't happen
with an opaque texture, so it's not due to max_gradient or accuracy.

-- 
Mike Williams
Gentleman of Leisure


Post a reply to this message

From: Mike
Subject: Re: Problem merging two isosurfaces
Date: 10 Oct 2008 20:20:01
Message: <web.48efeffec4ddaaeec9b9f9f00@news.povray.org>
Mike Williams <nos### [at] econymdemoncouk> wrote:
> Wasn't it Mike who wrote:
> >I have been trying to create basically a cube in which the top and bottom face
> >is a 2D sine wave (egg crate pattern).  I have been able to do this using
> >isosurface, with some trouble however.  The way I found to do this was to make
> >one isosurface sine wave pattern contained by a box and then make another one
> >also contained by a box and flip it over.  My problem is that when I try to
> >merge the two objects I create, I have tried merge and union I always see a
> >middle boundary in between them.  The indicies of refraction are matched and I
> >am using fresnel reflection, so I do not see how or why I am seeing this.  If
> >anyone has any ideas on how to make this artifact go away that would be very
> >helpful.  I have posted the code I used to make the object below.
>
> You could do this:
>
> global_settings {max_trace_level 50}
>
> #declare F = function {y-4.5 + .1*sin(3*6.2832*x)*sin(3*6.2832*z)}
>
> #declare WholeThing =
> isosurface {
>   function { abs(F(x,y,z))-0.5}
>   max_gradient 2.1
>   accuracy .0001
>   contained_by { box { <-1.8999, 3.9, -1.8999>, <1.8999, 5.1, 1.8999> }}
>   material { MixedRegion }
>
>   interior {
>     ior 1.400
>   }
>   photons{
>     target
>     refraction on
>     reflection on
>   }
> }
>
> I'm getting some dark specks. I don't know if that's due to
> max_trace_level, or my lighting, or if it's a real effect caused by
> small reflections or refractions of shadowed areas. They don't happen
> with an opaque texture, so it's not due to max_gradient or accuracy.
>
> --
> Mike Williams
> Gentleman of Leisure

Yeah, This got rid of the middle layer, but mine also has the added weird
specular effect. I do not think this is real because I did not see it when I
did my way original way, just this way.

-Mike


Post a reply to this message

From: Cousin Ricky
Subject: Re: Problem merging two isosurfaces
Date: 11 Oct 2008 22:45:00
Message: <web.48f1637ec4ddaaee85de7b680@news.povray.org>
"Mike" <win### [at] hotmailcom> wrote:
>   My problem is that when I try to
> merge the two objects I create, I have tried merge and union I always see a
> middle boundary in between them.  The indicies of refraction are matched and I
> am using fresnel reflection, so I do not see how or why I am seeing this.  If
> anyone has any ideas on how to make this artifact go away that would be very
> helpful.  I have posted the code I used to make the object below.

This looks like a coincident surface problem.  Usually this shows up as
speckles, but in your case it appears to have obliterated both surfaces.

The quick solution would have been to change the 3.2 to 3.4999 so that the
overlap area is only 0.0001--but that didn't eliminate the problem for me; it
only made it thinner.

But I like Mike Williams's solution better anyway.  The cast spots seem to be
from the egg-carton topology, although I can't think of why that would be.  But
once you turn on photons, they'll refract into a spotted pattern anyway, so I
wouldn't worry about them.


Post a reply to this message

From: Mike
Subject: Re: Problem merging two isosurfaces
Date: 13 Oct 2008 13:40:01
Message: <web.48f3876ac4ddaaeec9b9f9f00@news.povray.org>
Actually, I just tried it with photons on and it did not get rid of the
speckles.  Also, I do not think the speckles are from the egg crate pattern
since the frequency is too small and since this program does not seem to take
into account interference of waves, I don't think it would be possible to have
such a small frequency developing.  The reason I am being such a stickler with
this is that I plan on using this for visualizing an experiment and we would at
least try to minimize artifacts as much as possible.

-Mike




"Cousin Ricky" <ric### [at] yahoocom> wrote:
> "Mike" <win### [at] hotmailcom> wrote:
> >   My problem is that when I try to
> > merge the two objects I create, I have tried merge and union I always see a
> > middle boundary in between them.  The indicies of refraction are matched and I
> > am using fresnel reflection, so I do not see how or why I am seeing this.  If
> > anyone has any ideas on how to make this artifact go away that would be very
> > helpful.  I have posted the code I used to make the object below.
>
> This looks like a coincident surface problem.  Usually this shows up as
> speckles, but in your case it appears to have obliterated both surfaces.
>
> The quick solution would have been to change the 3.2 to 3.4999 so that the
> overlap area is only 0.0001--but that didn't eliminate the problem for me; it
> only made it thinner.
>
> But I like Mike Williams's solution better anyway.  The cast spots seem to be
> from the egg-carton topology, although I can't think of why that would be.  But
> once you turn on photons, they'll refract into a spotted pattern anyway, so I
> wouldn't worry about them.


Post a reply to this message

From: Alain
Subject: Re: Problem merging two isosurfaces
Date: 13 Oct 2008 19:05:47
Message: <48f3d44b$1@news.povray.org>
Mike nous illumina en ce 2008-10-13 13:37 -->
> Actually, I just tried it with photons on and it did not get rid of the
> speckles.  Also, I do not think the speckles are from the egg crate pattern
> since the frequency is too small and since this program does not seem to take
> into account interference of waves, I don't think it would be possible to have
> such a small frequency developing.  The reason I am being such a stickler with
> this is that I plan on using this for visualizing an experiment and we would at
> least try to minimize artifacts as much as possible.
> 
> -Mike
> 
> 
> 
> 
> "Cousin Ricky" <ric### [at] yahoocom> wrote:
>> "Mike" <win### [at] hotmailcom> wrote:
>>>   My problem is that when I try to
>>> merge the two objects I create, I have tried merge and union I always see a
>>> middle boundary in between them.  The indicies of refraction are matched and I
>>> am using fresnel reflection, so I do not see how or why I am seeing this.  If
>>> anyone has any ideas on how to make this artifact go away that would be very
>>> helpful.  I have posted the code I used to make the object below.
>> This looks like a coincident surface problem.  Usually this shows up as
>> speckles, but in your case it appears to have obliterated both surfaces.
>>
>> The quick solution would have been to change the 3.2 to 3.4999 so that the
>> overlap area is only 0.0001--but that didn't eliminate the problem for me; it
>> only made it thinner.
>>
>> But I like Mike Williams's solution better anyway.  The cast spots seem to be
>> from the egg-carton topology, although I can't think of why that would be.  But
>> once you turn on photons, they'll refract into a spotted pattern anyway, so I
>> wouldn't worry about them.
> 
> 
> 
> 
What can explain the speckling is multiple total internal reflections. At one 
pixel, you may have only a few, but the next pixel may need a max_trace_level 
near the maximum of 255.
Have you tried increasing adc_bailout? It limit the number on reflection and 
refractions based on the effective contribution to the colour returned by a ray. 
In some cases, it won't change a thing, in others, it can greatly help, and in 
still other, it may not be acceptable. Only experimentation can tell you if it's 
acceptable in a specific case.

In some cases, adding "all_intersections" can help.

-- 
Alain
-------------------------------------------------
   My wife is such a bad cook, in my house we pray after the meal.
   	Rodney Dangerfield


Post a reply to this message

From: Mike
Subject: Re: Problem merging two isosurfaces
Date: 14 Oct 2008 16:10:01
Message: <web.48f4fb76c4ddaaeec9b9f9f00@news.povray.org>
Alain <ele### [at] netscapenet> wrote:
> Mike nous illumina en ce 2008-10-13 13:37 -->
> > Actually, I just tried it with photons on and it did not get rid of the
> > speckles.  Also, I do not think the speckles are from the egg crate pattern
> > since the frequency is too small and since this program does not seem to take
> > into account interference of waves, I don't think it would be possible to have
> > such a small frequency developing.  The reason I am being such a stickler with
> > this is that I plan on using this for visualizing an experiment and we would at
> > least try to minimize artifacts as much as possible.
> >
> > -Mike
> >
> >
> >
> >
> > "Cousin Ricky" <ric### [at] yahoocom> wrote:
> >> "Mike" <win### [at] hotmailcom> wrote:
> >>>   My problem is that when I try to
> >>> merge the two objects I create, I have tried merge and union I always see a
> >>> middle boundary in between them.  The indicies of refraction are matched and I
> >>> am using fresnel reflection, so I do not see how or why I am seeing this.  If
> >>> anyone has any ideas on how to make this artifact go away that would be very
> >>> helpful.  I have posted the code I used to make the object below.
> >> This looks like a coincident surface problem.  Usually this shows up as
> >> speckles, but in your case it appears to have obliterated both surfaces.
> >>
> >> The quick solution would have been to change the 3.2 to 3.4999 so that the
> >> overlap area is only 0.0001--but that didn't eliminate the problem for me; it
> >> only made it thinner.
> >>
> >> But I like Mike Williams's solution better anyway.  The cast spots seem to be
> >> from the egg-carton topology, although I can't think of why that would be.  But
> >> once you turn on photons, they'll refract into a spotted pattern anyway, so I
> >> wouldn't worry about them.
> >
> >
> >
> >
> What can explain the speckling is multiple total internal reflections. At one
> pixel, you may have only a few, but the next pixel may need a max_trace_level
> near the maximum of 255.
> Have you tried increasing adc_bailout? It limit the number on reflection and
> refractions based on the effective contribution to the colour returned by a ray.
> In some cases, it won't change a thing, in others, it can greatly help, and in
> still other, it may not be acceptable. Only experimentation can tell you if it's
> acceptable in a specific case.
>
> In some cases, adding "all_intersections" can help.
>
> --
> Alain
> -------------------------------------------------
>    My wife is such a bad cook, in my house we pray after the meal.
>     Rodney Dangerfield


So, I tried both adding all_intersections, playing with adc_bailout (seems like
I should make it smaller to decrease the error it permits before "giving up"),
and I played with the max_trace. All of this did not fix it.  Actually, I
looked online and found someone who might have fixed the problem.
http://www.triplespark.net/render/povray/patches/isoacc-patch/
They edit isosurf.cpp.  I am not sure how to do this, I am using MegaPov on an
intel mac.

-Mike


Post a reply to this message

From: Mike
Subject: Re: Problem merging two isosurfaces
Date: 15 Oct 2008 13:00:00
Message: <web.48f6207dc4ddaaeec9b9f9f00@news.povray.org>
"Mike" <win### [at] hotmailcom> wrote:
> Alain <ele### [at] netscapenet> wrote:
> > Mike nous illumina en ce 2008-10-13 13:37 -->
> > > Actually, I just tried it with photons on and it did not get rid of the
> > > speckles.  Also, I do not think the speckles are from the egg crate pattern
> > > since the frequency is too small and since this program does not seem to take
> > > into account interference of waves, I don't think it would be possible to have
> > > such a small frequency developing.  The reason I am being such a stickler with
> > > this is that I plan on using this for visualizing an experiment and we would at
> > > least try to minimize artifacts as much as possible.
> > >
> > > -Mike
> > >
> > >
> > >
> > >
> > > "Cousin Ricky" <ric### [at] yahoocom> wrote:
> > >> "Mike" <win### [at] hotmailcom> wrote:
> > >>>   My problem is that when I try to
> > >>> merge the two objects I create, I have tried merge and union I always see a
> > >>> middle boundary in between them.  The indicies of refraction are matched and I
> > >>> am using fresnel reflection, so I do not see how or why I am seeing this.  If
> > >>> anyone has any ideas on how to make this artifact go away that would be very
> > >>> helpful.  I have posted the code I used to make the object below.
> > >> This looks like a coincident surface problem.  Usually this shows up as
> > >> speckles, but in your case it appears to have obliterated both surfaces.
> > >>
> > >> The quick solution would have been to change the 3.2 to 3.4999 so that the
> > >> overlap area is only 0.0001--but that didn't eliminate the problem for me; it
> > >> only made it thinner.
> > >>
> > >> But I like Mike Williams's solution better anyway.  The cast spots seem to be
> > >> from the egg-carton topology, although I can't think of why that would be.  But
> > >> once you turn on photons, they'll refract into a spotted pattern anyway, so I
> > >> wouldn't worry about them.
> > >
> > >
> > >
> > >
> > What can explain the speckling is multiple total internal reflections. At one
> > pixel, you may have only a few, but the next pixel may need a max_trace_level
> > near the maximum of 255.
> > Have you tried increasing adc_bailout? It limit the number on reflection and
> > refractions based on the effective contribution to the colour returned by a ray.
> > In some cases, it won't change a thing, in others, it can greatly help, and in
> > still other, it may not be acceptable. Only experimentation can tell you if it's
> > acceptable in a specific case.
> >
> > In some cases, adding "all_intersections" can help.
> >
> > --
> > Alain
> > -------------------------------------------------
> >    My wife is such a bad cook, in my house we pray after the meal.
> >     Rodney Dangerfield
>
>
> So, I tried both adding all_intersections, playing with adc_bailout (seems like
> I should make it smaller to decrease the error it permits before "giving up"),
> and I played with the max_trace. All of this did not fix it.  Actually, I
> looked online and found someone who might have fixed the problem.
> http://www.triplespark.net/render/povray/patches/isoacc-patch/
> They edit isosurf.cpp.  I am not sure how to do this, I am using MegaPov on an
> intel mac.
>
> -Mike



I tried the patch and it does not seem to do much else besides speeding up the
processing time (It uses a better root finding algorithm).  Actually, I notice
that if I lower the refractive index of my material the black dots go away, so
it definitely is a total internal reflection thing.  Also, it seems that by
turning off adc_bailout (seting equal to 0 ) and messing with the
max_trace_level I can make less black dots appear.  However, I have yet to be
able to make max_trace_level equal to 255 with adc_bailout off because it takes
too long to render.  Maybe I do not fully understand how adc_bailout works, it
seems if I make it really small I get no change from if I have it not there at
all (the default value).  Any ideas.

-Mike


Post a reply to this message

From: Trevor G Quayle
Subject: Re: Problem merging two isosurfaces
Date: 15 Oct 2008 15:35:00
Message: <web.48f64533c4ddaaee81c811d20@news.povray.org>
"Mike" <win### [at] hotmailcom> wrote:
> I have been trying to create basically a cube in which the top and bottom face
> is a 2D sine wave (egg crate pattern).  I have been able to do this using
> isosurface, with some trouble however.  The way I found to do this was to make
> one isosurface sine wave pattern contained by a box and then make another one
> also contained by a box and flip it over.  My problem is that when I try to
> merge the two objects I create, I have tried merge and union I always see a
> middle boundary in between them.  The indicies of refraction are matched and I
> am using fresnel reflection, so I do not see how or why I am seeing this.  If
> anyone has any ideas on how to make this artifact go away that would be very
> helpful.  I have posted the code I used to make the object below.

For what you are doing a heightfield would be far better suited and much easier
to work with.  See below.  You'll need to work with the values to get what you
want for scalings and translations.  The RES parameter adjusts the resolution
used for the heightfield.

Some things to note:
-HFs are created on the X/Z plane from <0,0> to <1,1>
-HFs read the function on the X/Y plane at Z=0  (ie, HF read from XY plane but
create on XZ plane - perpedicular)
-HF height is in the Y axis and ranges from 0 to 1, but actually acts like a
plane, ie, it is infinite below the surface (doesn't stop at 0)


This object should render far faster than an isosurface without errors or holes.
Higher values for RES will give more accurate results but will increase parse
time, however they shouldn't significantly affect render time.

Hope some of this helps.

-tgq



//START
#declare f_1= function (x,y){( 0.9-0.1*sin(3*6.2832*x)*sin(3*6.2832*y))}

#declare RES=100; //hf resolution
#local HF1=
  height_field{
    function RES,RES {pattern{ function {
      f_1 (x*1.9,y*1.9)
    }
   }
  }
  smooth
  translate <-1/2,-1/2,-1/2>
  scale <2.01,2,2.01> //scale the HF slightly larger in X/Z directions to be
removed
}

intersection{
  object{HF1 pigment {rgb 1}}  //Top HF
  object{HF1 rotate 180*z pigment {rgb 1}}  //Bottom HF
  box{-1,1 pigment {rgb 1}}  //Cube to trim sides
  scale <1.9,1,1.9>
}

//END


Post a reply to this message

From: Mike
Subject: Re: Problem merging two isosurfaces
Date: 16 Oct 2008 15:15:00
Message: <web.48f791c6c4ddaaeec9b9f9f00@news.povray.org>
"Trevor G Quayle" <Tin### [at] hotmailcom> wrote:
> "Mike" <win### [at] hotmailcom> wrote:
> > I have been trying to create basically a cube in which the top and bottom face
> > is a 2D sine wave (egg crate pattern).  I have been able to do this using
> > isosurface, with some trouble however.  The way I found to do this was to make
> > one isosurface sine wave pattern contained by a box and then make another one
> > also contained by a box and flip it over.  My problem is that when I try to
> > merge the two objects I create, I have tried merge and union I always see a
> > middle boundary in between them.  The indicies of refraction are matched and I
> > am using fresnel reflection, so I do not see how or why I am seeing this.  If
> > anyone has any ideas on how to make this artifact go away that would be very
> > helpful.  I have posted the code I used to make the object below.
>
> For what you are doing a heightfield would be far better suited and much easier
> to work with.  See below.  You'll need to work with the values to get what you
> want for scalings and translations.  The RES parameter adjusts the resolution
> used for the heightfield.
>
> Some things to note:
> -HFs are created on the X/Z plane from <0,0> to <1,1>
> -HFs read the function on the X/Y plane at Z=0  (ie, HF read from XY plane but
> create on XZ plane - perpedicular)
> -HF height is in the Y axis and ranges from 0 to 1, but actually acts like a
> plane, ie, it is infinite below the surface (doesn't stop at 0)
>
>
> This object should render far faster than an isosurface without errors or holes.
> Higher values for RES will give more accurate results but will increase parse
> time, however they shouldn't significantly affect render time.
>
> Hope some of this helps.
>
> -tgq
>
>
>
> //START
> #declare f_1= function (x,y){( 0.9-0.1*sin(3*6.2832*x)*sin(3*6.2832*y))}
>
> #declare RES=100; //hf resolution
> #local HF1=
>   height_field{
>     function RES,RES {pattern{ function {
>       f_1 (x*1.9,y*1.9)
>     }
>    }
>   }
>   smooth
>   translate <-1/2,-1/2,-1/2>
>   scale <2.01,2,2.01> //scale the HF slightly larger in X/Z directions to be
> removed
> }
>
> intersection{
>   object{HF1 pigment {rgb 1}}  //Top HF
>   object{HF1 rotate 180*z pigment {rgb 1}}  //Bottom HF
>   box{-1,1 pigment {rgb 1}}  //Cube to trim sides
>   scale <1.9,1,1.9>
> }
>
> //END



Thanks for the advice, this works much better.  However, when I switch the
material to the same as that I have been using (translucent, ior =1.5) I still
get black dots however not as much.  Actually, I have noticed that I can nearly
get rid of them by turning off adc_bailout (setting it equal to zero) and
increasing the max_trace_level.  I am having trouble going anywhere above
around 50 for the max_trace_level with the adc_bailout off (it takes forever to
render).  I would really like it if someone could explain the adc_bailout to me
a bit better than what is given in the documentation.  Is there a lower limit?
I think what I would actually want to do is make adc_bailout really small as to
retain the affect of max_trace_level, but I am not seeing this.  It seems with
adc_bailout on, no matter what the value (when made smaller than the default
because larger only makes things worse) a change in max_trace_level does
nothing.
Here is the updated piece of code you gave me that I have been running:

  #declare MixedRegion =
material {
   texture {
     pigment {
        color rgbf<0.3, 0.5, .5,1>
      }

 finish {
        ambient 0.0
        diffuse 0.0
         reflection {
          0.0, 1.0
          fresnel on
        }
        conserve_energy
        specular 0.0
        roughness 0.0
 }
  }
  }

#declare f_1= function (x,y){( 0.9-0.1*sin(3*6.2832*x)*sin(3*6.2832*y))}

#declare RES=6000; //hf resolution
#local HF1=
  height_field{
    function RES,RES {pattern{ function {
      f_1 (x*1.9,y*1.9)
    }
   }
  }
  smooth
  translate <-1/2,-1/2,-1/2>
  scale <2.01,2,2.01> //scale the HF slightly larger in X/Z directions to be
removed
}

#declare Mixingregion3=
intersection{
  object{HF1 material { MixedRegion } interior {ior 1.5} }  //Top HF
  object{HF1 rotate 180*z material { MixedRegion } interior {ior 1.5}}  //Bottom
HF
  box{-1,1 material { MixedRegion } interior {ior 1.5}}  //Cube to trim sides
  scale <1.9,1,1.9>
  translate 4*y
  //material { MixedRegion }
  //interior {ior 1.5}
}

object{Mixingregion3}

-Mike


Post a reply to this message

Goto Latest 10 Messages Next 1 Messages >>>

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