POV-Ray : Newsgroups : povray.beta-test : Function context issue. : Re: Function context issue. Server Time
31 Jul 2024 00:22:45 EDT (-0400)
  Re: Function context issue.  
From: Mike Williams
Date: 21 Sep 2001 02:15:32
Message: <tPqweDAHhtq7Ewwm@econym.demon.co.uk>
Wasn't it Batronyx who wrote:
>Please see my previous post "Problem in pigment_pattern
>with bozo/f_noise3d:" for a set of code illustrating
>this issue.
>
>After thoroughly reviewing the docs, Mike Williams' excellent tutorial,
>several posts, and lots of personal research, I've decided what I wanted
>to do just can't be done. If I'm wrong maybe someone here can set me
>straight. :)
>
>Take the following code snippet:
>//-------------------------------
>
>#declare Fn_AmbMap = function{ pigment{
>       pigment_pattern {bozo scale 0.5}
>                   color_map {
>        [0.00 color rgb <0,0,0> ]
>        [1.00 color rgb <1,1,1> ]
>      }
>   }
>}//end function
>.
>.
>.
>texture{ pigment {function{Fn_AmbMap(x,y,z).gray}scale 0.5 }
>         finish {diffuse pow((Fn_AmbMap(x.x,y.y,z.z).gray),1)}
>  }
>//----------------------------------
>
>It shows a function definition and two uses of the function
>in two different contexts: as a pigment and as a user defined
>float function. Of note here are the two different forms the
>parameters are required to take. This has been a source of some
>confusion, usually resulting in an explanation of the differences
>between floats and vectors.The real issue however has to do with
>context, since the statement above is perfectly legal.

Actually, I believe that this is the critical point.

The problem is that "x" can have two possible meanings. One meaning is
the float value of the x-coordinate of the point that the function is
currently evaluating, and the other is the unit vector <1,0,0>. At parse
time, only the unit vector interpretation is meaningful.

In this case, POV has decided that "x" in this context means <1,0,0>,
which happens to not be the interpretation that you desire.

Wherever "x." is meaningful, it will always mean the x component of
<1,0,0>, i.e. the value 1. Similarly "x.x,y.y,z.z" is the point <1,1,1>.
So "(Fn_AmbMap(x.x,y.y,z.z).gray" always evaluates the function at the
point <1,1,1>.

(Quick check: Your scene does render identically with x.x,y.y,z.z
replaced throughout with 1,1,1.)


>However, it does not do what I was hoping it would; vary the
>diffusion across the surface. The reason, it seems, is there is no
>way to 'explicitly' pass in the vector coordinates of the current
>ray-intersection point. This is done 'implicitly' in the context
>of the pigment, normal, isosurface, and (depending on final usage context)
>possibly also other function declarations.

I think that there may well be a syntax that does this explicitly, but
you can only use it where it is allowed, and it doesn't happen to be
currently allowed after "diffuse". If it were allowed it would look like
this
  finish {diffuse function{F(x,y,z)}}
rather than
  finish {diffuse F(x,y,z)}

It looks to me that if you use a function without outside a "function{}"
envelope, then it gets evaluated at parse time. e.g.
     pigment {rgb Fn_AmbMap(1,1,1)}


>Without this explicit mechanism, the function is fully evaluated at
>parse time and if called during render time by the pseudo-code engine
>redundantly returns the same value at each call. It is unnecessary
>overhead then, since, ( as I understand it ) with respect to functions the only
>thing to change during the render are the vector coordinates of the current
>point under evaluation. A macro or something would be more
>appropriate here if only to save render overhead.

I understood that functions were faster than macros.


-- 
Mike Williams
Gentleman of Leisure


Post a reply to this message

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