POV-Ray : Newsgroups : povray.general : Isosurface oddity Server Time
27 Nov 2024 00:39:52 EST (-0500)
  Isosurface oddity (Message 1 to 6 of 6)  
From: Doctor John
Subject: Isosurface oddity
Date: 13 Jul 2009 10:23:28
Message: <4a5b4360@news.povray.org>
I've just come across an unusual bit of behaviour when rendering a large
number of similar isosurfaces.
When I use the code:
> #declare Index = 0;
> #while (Index<29)
> 	isosurface {
> 		function {f_rounded_box(x, y, z, 0.1, 1.19, 0.3, 0.4)+f_granite(x+rand(Seed),
>		y+rand(Seed), z+rand(Seed))*0.09}
I get the message:
> Parse Error: Expected 'function identifier', } found instead
However, when I use:
> #declare Index = 0;
> #while (Index<29)
> #local RX=rand(Seed);
> #local RY=rand(Seed);
> #local RZ=rand(Seed);
> 	isosurface {
> 		function {f_rounded_box(x, y, z, 0.1, 1.19, 0.3, 0.4)+f_granite(x+RX,
>		y+RY, z+RZ)*0.09}
Everything works as expected.
What's happening? Surely Pov's only got to look up the next number in
the random stream which can't be much different from looking up the
values of the declared variables.

John (scratching his head in confusion)
-- 
"Eppur si muove" - Galileo Galilei


Post a reply to this message

From: Alain
Subject: Re: Isosurface oddity
Date: 13 Jul 2009 10:59:29
Message: <4a5b4bd1$1@news.povray.org>

> I've just come across an unusual bit of behaviour when rendering a large
> number of similar isosurfaces.
> When I use the code:
>> #declare Index = 0;
>> #while (Index<29)
>> 	isosurface {
>> 		function {f_rounded_box(x, y, z, 0.1, 1.19, 0.3, 0.4)+f_granite(x+rand(Seed),
>> 		y+rand(Seed), z+rand(Seed))*0.09}
> I get the message:
>> Parse Error: Expected 'function identifier', } found instead
> However, when I use:
>> #declare Index = 0;
>> #while (Index<29)
>> #local RX=rand(Seed);
>> #local RY=rand(Seed);
>> #local RZ=rand(Seed);
>> 	isosurface {
>> 		function {f_rounded_box(x, y, z, 0.1, 1.19, 0.3, 0.4)+f_granite(x+RX,
>> 		y+RY, z+RZ)*0.09}
> Everything works as expected.
> What's happening? Surely Pov's only got to look up the next number in
> the random stream which can't be much different from looking up the
> values of the declared variables.
> 
> John (scratching his head in confusion)

There is a big difference:
When you trace an isosurface, you take several samples inside the 
container, each time evaluating the function. You must take several 
samples for each ray that enters the container untill you actualy find a 
surface.

In the first case, you'd need to fetch a new random value EACH time you 
sample the container to see if you've found the surface. This makes for 
several random values for each ray. This would makes the isosurface 
looks like a ball of dust if it was allowed. As you progress toward the 
surface, one sample detect that it's should be well ahead, then, the 
next sample detects that the surface that should still be ahead is now 
beheind. Most of the time, the surface can't be found and you pass right 
trough your object.

In the second case, you get a random value ONCE for each direction. The 
random value is constent everywhere, and shifts the surface in a random, 
but constant, direction.



Alain


Post a reply to this message

From: Warp
Subject: Re: Isosurface oddity
Date: 13 Jul 2009 11:06:28
Message: <4a5b4d74@news.povray.org>
Doctor John <joh### [at] homecom> wrote:
> I've just come across an unusual bit of behaviour when rendering a large
> number of similar isosurfaces.
> When I use the code:
> > #declare Index = 0;
> > #while (Index<29)
> >       isosurface {
> >               function {f_rounded_box(x, y, z, 0.1, 1.19, 0.3,
0.4)+f_granite(x+rand(Seed),
> >               y+rand(Seed), z+rand(Seed))*0.09}
> I get the message:
> > Parse Error: Expected 'function identifier', } found instead
> However, when I use:
> > #declare Index = 0;
> > #while (Index<29)
> > #local RX=rand(Seed);
> > #local RY=rand(Seed);
> > #local RZ=rand(Seed);
> >       isosurface {
> >               function {f_rounded_box(x, y, z, 0.1, 1.19, 0.3,
0.4)+f_granite(x+RX,
> >               y+RY, z+RZ)*0.09}
> Everything works as expected.
> What's happening? Surely Pov's only got to look up the next number in
> the random stream which can't be much different from looking up the
> values of the declared variables.

  rand() is not a function supported inside user-defined functions, it's
that simple.

  (While user-defined functions and SDL math expressions might look similar,
they are completely separate. It can get a bit confusing sometimes.)

-- 
                                                          - Warp


Post a reply to this message

From: Doctor John
Subject: Re: Isosurface oddity
Date: 13 Jul 2009 11:19:26
Message: <4a5b507e@news.povray.org>
Warp wrote:
> 
>   rand() is not a function supported inside user-defined functions, it's
> that simple.
> 
>   (While user-defined functions and SDL math expressions might look similar,
> they are completely separate. It can get a bit confusing sometimes.)
> 
Light dawns. Thanks for the explanation. As you can see I wasn't worried
'cos I could work out the work-around.

John
-- 
"Eppur si muove" - Galileo Galilei


Post a reply to this message

From: clipka
Subject: Re: Isosurface oddity
Date: 14 Jul 2009 10:25:00
Message: <web.4a5c95049e56e3e95fee4dc70@news.povray.org>
Doctor John <joh### [at] homecom> wrote:
> What's happening? Surely Pov's only got to look up the next number in
> the random stream which can't be much different from looking up the
> values of the declared variables.

This is really not an isosurface-specific issue; you get this error message
whenever you try to use rand() in a function.

There's two answers to your question - a short one and a long one:

(A) POV-Ray only supports a reduced set of built-in keywords in functions;
rand() is one of those not supported there, hence the error message.

(B) The POV-Ray function mechanism was designed for terms that need to be
evaluated over and over at run-time; for instance, to find even a single
ray-isosurface intersection, the defining function needs to be evaluated
multiple times over and over again with varying arguments. Therefore, a rand()
placed inside such a defining function would theoretically be evaluated over
and over again, too - creating a function that would change not only over
space, but also over "time" (even in a highly erratic way), which would
perfectly wreck the isosurface algorithm (aside from obviously not being what
you want).

So in order for this to work, the random value needs to be evaluated *before*
storing the function for later use - which is just what your second construct
does. To have POV-Ray automatically do this would require implementing special
treatment for the rand() keyword - which in other circumstances may *not* be
what the user would expect (for instance, someone might try to implement a
non-uniformly distributed random generator, using the function framework
instead of a macro).

Speaking of macros: As a matter of fact, if you need this idiom (using
rand()-generated values in a isosurface-defining function) frequently, you can
save some of the work by defining a Rand() macro as follows:

    #macro Rand(stream)
      #declare R = rand(stream);
      R
    #end

As macros are *always* evaluated at compile-time, and #declare statements are
valid everywhere, you could now place the call anywhere, even in a function
definition, without creating ambiguities or "misbehaving" functions.


Post a reply to this message

From: Doctor John
Subject: Re: Isosurface oddity
Date: 15 Jul 2009 06:21:26
Message: <4a5dada6@news.povray.org>
clipka wrote:
> 
> There's two answers to your question - a short one and a long one:
> 

When possible I always go for the long version.
Now I understand. :-)

> Speaking of macros: As a matter of fact, if you need this idiom (using
> rand()-generated values in a isosurface-defining function) frequently, you can
> save some of the work by defining a Rand() macro as follows:
> 
>     #macro Rand(stream)
>       #declare R = rand(stream);
>       R
>     #end
> 
> As macros are *always* evaluated at compile-time, and #declare statements are
> valid everywhere, you could now place the call anywhere, even in a function
> definition, without creating ambiguities or "misbehaving" functions.

Useful. Thanks for the help

John
-- 
"Eppur si muove" - Galileo Galilei


Post a reply to this message

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