|
|
|
|
|
|
| |
| |
|
|
|
|
| |
| |
|
|
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
|
|
| |
| |
|
|
|
|
| |
| |
|
|
> 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
|
|
| |
| |
|
|
|
|
| |
| |
|
|
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
|
|
| |
| |
|
|
|
|
| |
| |
|
|
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
|
|
| |
| |
|
|
|
|
| |
| |
|
|
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
|
|
| |
| |
|
|
|
|
| |
| |
|
|
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
|
|
| |
| |
|
|
|
|
| |
|
|