POV-Ray : Newsgroups : povray.programming : Re: Problem with f_rounded_box function Server Time
17 May 2024 06:00:40 EDT (-0400)
  Re: Problem with f_rounded_box function (Message 3 to 12 of 12)  
<<< Previous 2 Messages Goto Initial 10 Messages
From: Christoph Hormann
Subject: Re: Problem with f_rounded_box function
Date: 9 Mar 2006 11:55:03
Message: <dupme5$rqb$1@chho.imagico.de>
Sebastian H. wrote:
> Sebastian H. wrote:
> 
>> problem/bug?
> 

The docs are wrong, f_rounded_box() should only be used with radius > 0. 
  This is not a bug but simply a limitation (although it would of course 
make sense to add an efficient handling of the case radius=0).

Note the current f_rounded_box() is not a very efficient solution anyway 
(you don't need an sqrt() for every evaluation).

> I dug a bit in the source code and found that a
> change in fnintern.cpp fixes the problem.
> In the f_rounded_box function there is an offset
> of 1e-6 subtracted from the actual result.
> 
> return (... - 1e-6);
> 
> With an increased offset magnitude of 1e-3
> the problem disappears and the isosurface looks correct.
> Why this offset is there is beyond me but removing it
> slows down the isosurface rendering a lot.

To me it seems this offset is specifically for handling the degenerate 
case.  Choosing 1e-3 simply gets you beyond your accuracy limit.

Christoph

-- 
POV-Ray tutorials, include files, Landscape of the week:
http://www.imagico.de/ (Last updated 31 Oct. 2005)
MegaPOV with mechanics simulation: http://megapov.inetart.net/


Post a reply to this message

From: Sebastian H 
Subject: Re: Problem with f_rounded_box function
Date: 12 Mar 2006 16:51:44
Message: <441497f0$1@news.povray.org>
Mike Williams wrote:

> I noticed that the slow down only seems to be happening with the
> processing of shadows. If you add the no_shadow keyword, or move both
> lights round to the front, then the isosurface renders quickly, but it
> still has speckles.
> 

I tried a scene with many isosurface with different parameters for
f_rounded_box and found that removing the offset reduces the overall
render time for the scene by about 2%. Though "a lot" slowdown is
overestimated it is noticeable.

I have a wip scene which uses f_rounded_box a lot and unfortunately
no shadow is not an option. But thank you for the hint anyway.

Sebastian


Post a reply to this message

From: Sebastian H 
Subject: Re: Problem with f_rounded_box function
Date: 12 Mar 2006 17:09:40
Message: <44149c24@news.povray.org>
Christoph Hormann wrote:
> The docs are wrong, f_rounded_box() should only be used with radius > 0. 
>  This is not a bug but simply a limitation (although it would of course 
> make sense to add an efficient handling of the case radius=0).
> 
> Note the current f_rounded_box() is not a very efficient solution anyway 
> (you don't need an sqrt() for every evaluation).
Actually I tried the following expression.

return (PARAM_X * PARAM_X
  + PARAM_Y * PARAM_Y
  + PARAM_Z * PARAM_Z
  - PARAM(0)*PARAM(0));

against

return (
  sqrt(PARAM_X * PARAM_X
  + PARAM_Y * PARAM_Y
  + PARAM_Z * PARAM_Z)
  - PARAM(0));

And found that the latter was always faster by about 30%.
I'm not exactly sure why it is that way but one problem
is that a the max_gradient needs higher values.
For the former version a max_gradient of 1.0 is always
suitable whereas for the latter one something
like

2.0*sqrt(3)*RADIUS

is neccessary.
There may be parameters for which the latter one is faster
but in the geral case the square root beats the square.
A least this is the result from the tests renders I did
on my pentium-m 1300MHz machine.

The most promissing solution I found looks like this.

DBL f_rounded_box(DBL *ptr, unsigned int) // 60
{

   DBL x2, y2, z2, x3, y3, z3;

   x2 = PARAM(1) - PARAM(0);
   y2 = PARAM(2) - PARAM(0);
   z2 = PARAM(3) - PARAM(0);

   x3 = fabs(PARAM_X);
   y3 = fabs(PARAM_Y);
   z3 = fabs(PARAM_Z);

   PARAM_X = (x3 < x2) ? 0 : (x3 - x2);
   PARAM_Y = (y3 < y2) ? 0 : (y3 - y2);
   PARAM_Z = (z3 < z2) ? 0 : (z3 - z2);

return (sqrt(PARAM_X * PARAM_X + PARAM_Y * PARAM_Y + PARAM_Z * PARAM_Z) 
  - PARAM(0));

}

Using fabs gave me approx. 2% speed increase in the test scene
(p.b.images).

> 
> To me it seems this offset is specifically for handling the degenerate 
> case.  Choosing 1e-3 simply gets you beyond your accuracy limit.

This was my intention. And yes, this is very likely. I tried the
degenerated case without the offset and the render process stuck
on the first line until I aborted after some minutes.

Sebastian


Post a reply to this message

From: Christoph Hormann
Subject: Re: Problem with f_rounded_box function
Date: 12 Mar 2006 17:35:02
Message: <dv27jm$bsr$1@chho.imagico.de>
Sebastian H. wrote:
>>
>> Note the current f_rounded_box() is not a very efficient solution 
>> anyway (you don't need an sqrt() for every evaluation).
> 
> Actually I tried the following expression.
> 
> return (PARAM_X * PARAM_X
>  + PARAM_Y * PARAM_Y
>  + PARAM_Z * PARAM_Z
>  - PARAM(0)*PARAM(0));
> 

That's not what i meant.  You don't need the sqrt() on the faces of the 
rounded cube - there a simple plane function is sufficient.

Christoph

-- 
POV-Ray tutorials, include files, Landscape of the week:
http://www.imagico.de/ (Last updated 31 Oct. 2005)
MegaPOV with mechanics simulation: http://megapov.inetart.net/


Post a reply to this message

From: Sebastian H 
Subject: Re: Problem with f_rounded_box function
Date: 12 Mar 2006 18:39:55
Message: <4414b14b$1@news.povray.org>
Christoph Hormann wrote:
> Sebastian H. wrote:
> 
> That's not what i meant.  You don't need the sqrt() on the faces of the 
> rounded cube - there a simple plane function is sufficient.

Hmm, needs some "if" calls but gives another speed boost of
approx. 8% in the test image.
The function now looks like this.

DBL f_rounded_box(DBL *ptr, unsigned int) // 60
{
   DBL x2, y2, z2, x3, y3, z3;

   x2 = PARAM(1) - PARAM(0);
   y2 = PARAM(2) - PARAM(0);
   z2 = PARAM(3) - PARAM(0);

   x3 = fabs(PARAM_X);
   y3 = fabs(PARAM_Y);
   z3 = fabs(PARAM_Z);

   PARAM_X = (x3 < x2) ? 0 : (x3 - x2);
   PARAM_Y = (y3 < y2) ? 0 : (y3 - y2);
   PARAM_Z = (z3 < z2) ? 0 : (z3 - z2);

   // With coitus interruptus
   if(!PARAM_X)
     {
       if(!PARAM_Y)
	{
	  return (z3 - PARAM(3));
	}
       if(!PARAM_Z)
	{
	  return (y3 - PARAM(2));
	}
     }

   if((!PARAM_Y) && (!PARAM_Z))
     {
       return (x3 - PARAM(1));
     }

   return (sqrt(PARAM_X * PARAM_X + PARAM_Y * PARAM_Y + PARAM_Z * 
PARAM_Z)  - PARAM(0));

}

Now there appear gradients above 1.0 but I could not find
any surface errors so I think a max_gradient of 1.0 is still fine.

If anyone wants to put this code or part of into the official source
feel free.

Sebastian


Post a reply to this message

From: Christoph Hormann
Subject: Re: Problem with f_rounded_box function
Date: 13 Mar 2006 04:25:03
Message: <dv3do9$j7c$1@chho.imagico.de>
Sebastian H. wrote:
> 
>> Sebastian H. wrote:
>>
>> That's not what i meant.  You don't need the sqrt() on the faces of 
>> the rounded cube - there a simple plane function is sufficient.
> 
> 
> Hmm, needs some "if" calls 

Yes, that's what i meant.  I would however do it somewhat differently 
(untested, based on what you wrote):

{
   DBL x2, y2, z2, x3, y3, z3;

   x2 = PARAM(1) - PARAM(0);
   y2 = PARAM(2) - PARAM(0);
   z2 = PARAM(3) - PARAM(0);

   x3 = fabs(PARAM_X);
   y3 = fabs(PARAM_Y);
   z3 = fabs(PARAM_Z);

   if (x3 < x2)
   {
     if (y3 < y2)
     {
       if (z3 < z2)
       {
         return -PARAM(0);
       }
       return (z3 - PARAM(3));
     }
     if (z3 < z2)
     {
       return (y3 - PARAM(2));
     }
     return (sqrt(PARAM_Y * PARAM_Y + PARAM_Z * PARAM_Z)  - PARAM(0));
   }

   if (y3 < y2)
   {
     if (z3 < z2)
     {
       return (x3 - PARAM(1));
     }
     return (sqrt(PARAM_X * PARAM_X + PARAM_Z * PARAM_Z)  - PARAM(0));
   }

   if (z3 < z2)
   {
     return (sqrt(PARAM_X * PARAM_X + PARAM_Y * PARAM_Y)  - PARAM(0));
   }

   return (sqrt(PARAM_X * PARAM_X + PARAM_Y * PARAM_Y + PARAM_Z * 
PARAM_Z)  - PARAM(0));
}

It would BTW be easy to add a correct distance function for the interior 
as well by replacing the 'return -PARAM(0);'.  This would of course 
break backwards compatibility so it might not be a good idea.

Christoph

-- 
POV-Ray tutorials, include files, Landscape of the week:
http://www.imagico.de/ (Last updated 31 Oct. 2005)
MegaPOV with mechanics simulation: http://megapov.inetart.net/


Post a reply to this message

From: Sebastian H 
Subject: Re: Problem with f_rounded_box function
Date: 13 Mar 2006 05:55:38
Message: <44154faa$1@news.povray.org>
Christoph Hormann wrote:
> Yes, that's what i meant.  I would however do it somewhat differently 
> (untested, based on what you wrote):

There's a problem with the PARAM_* used in the square roots.
Actually they are the distance from the "inner box" and must
be redefined as such before with the code you dropped.
(Abusing the parameters for this is a bit ugly, but...)

   PARAM_X = x3 - x2;
   PARAM_Y = y3 - y2;
   PARAM_Z = z3 - z2;

The addition of the square roots with reduced argument number looks good
though I'm not sure whether by the third one anything is gained.
It's one additional comparison to maybe save one multiplication and
one addition.

> It would BTW be easy to add a correct distance function for the interior 
> as well by replacing the 'return -PARAM(0);'.  This would of course 
> break backwards compatibility so it might not be a good idea.

It seems that the return -PARAM(0) also cures the max. gradient peaks.

Sebastian


Post a reply to this message

From: Christoph Hormann
Subject: Re: Problem with f_rounded_box function
Date: 13 Mar 2006 07:15:03
Message: <dv3nib$8ku$1@chho.imagico.de>
Sebastian H. wrote:
> 
> There's a problem with the PARAM_* used in the square roots.
> Actually they are the distance from the "inner box" and must
> be redefined as such before with the code you dropped.
> (Abusing the parameters for this is a bit ugly, but...)
> 
>   PARAM_X = x3 - x2;
>   PARAM_Y = y3 - y2;
>   PARAM_Z = z3 - z2;

As said - i did not yet test it.

> The addition of the square roots with reduced argument number looks good
> though I'm not sure whether by the third one anything is gained.
> It's one additional comparison to maybe save one multiplication and
> one addition.

Well - the most important reason is to maintain the beauty of symmetry 
in the code... ;-)

Christoph

-- 
POV-Ray tutorials, include files, Landscape of the week:
http://www.imagico.de/ (Last updated 31 Oct. 2005)
MegaPOV with mechanics simulation: http://megapov.inetart.net/


Post a reply to this message

From: Sebastian H 
Subject: Re: Problem with f_rounded_box function
Date: 15 Mar 2006 04:45:06
Message: <4417e222@news.povray.org>
Christoph Hormann wrote:
> 
> Well - the most important reason is to maintain the beauty of symmetry 
> in the code... ;-)

And the winning title is "A reflection of geometry in C"... :-)

I did some further investigation and compared four different
incarnations of f_rounded_box. The winner, at least on my pentium-m
machine, is version 5 (All versions are in the attachement).

For the comparison the (debian sarge) machine was switched into single
user mode and (hopefully) all unneccesary tasks were shut down. Then the
test scene (p.b.scene-files) were rendered 8 times each with no
jitter/AA at 8000x4500.
A plot of the render times is in p.b.images.

Astonishing is that version 5 is faster than version 8
although the latter one contains a simpler square root function.
Probably some compiler optimization (g++ (GCC) 3.3.5 (Debian 
1:3.3.5-13)) jumped in in version 5.

Regards,
Sebastian

P.S.: The second attachement contains the render times for the test
scene.


Post a reply to this message


Attachments:
Download 'us-ascii' (3 KB) Download 'times.dat.txt' (1 KB)

From: Christoph Hormann
Subject: Re: Problem with f_rounded_box function
Date: 15 Mar 2006 06:55:03
Message: <dv8v5p$mud$1@chho.imagico.de>
Sebastian H. wrote:
> [...]
> 
> Astonishing is that version 5 is faster than version 8
> although the latter one contains a simpler square root function.
> Probably some compiler optimization (g++ (GCC) 3.3.5 (Debian 
> 1:3.3.5-13)) jumped in in version 5.

But those differences are marginal - and it is very likely that 
interferences between code, compiler optimizations and processor design 
play a role here.  So there is no reason to select a certain code 
variant based on this.

But anyway this is a good demonstration that these days simple 
estimations of efficiency of code based on counting elementary 
operations is not working.

Christoph

-- 
POV-Ray tutorials, include files, Landscape of the week:
http://www.imagico.de/ (Last updated 14 Mar. 2006)
MegaPOV with mechanics simulation: http://megapov.inetart.net/


Post a reply to this message

<<< Previous 2 Messages Goto Initial 10 Messages

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