Difference between revisions of "Reference:Function"
Jholsenback (talk | contribs) m (escaped newline in two places) |
(indexentry fix) |
||
Line 1: | Line 1: | ||
− | {{#indexentry:Functions, user-defined | + | {{#indexentry:Functions, user-defined}} |
+ | {{#indexentry:Functions}} | ||
{{#indexentry:function}} | {{#indexentry:function}} | ||
<p>Some objects allow you to specify functions that will be evaluated while rendering to determine the surface of these objects. In this respect functions are quite different to [[Reference:User Defined Macros|:#macro|macros]], which are evaluated at parse time but do not otherwise affect rendering. Additionally you may call these functions anywhere a Float Function is allowed, even during parsing. The syntax is identical to Float Expressions, however, only float functions that apply to float values may be used. Excluded are for example <code><!--<linkto "strlen">strlen</linkto>--->[[Reference:Numeric Expressions#Functions|strlen]]</code> or <code>[[Reference:Numeric Expressions#Functions|:vlength|vlength]]</code>. You find a full list of supported float functions in the syntax definition below.</p> | <p>Some objects allow you to specify functions that will be evaluated while rendering to determine the surface of these objects. In this respect functions are quite different to [[Reference:User Defined Macros|:#macro|macros]], which are evaluated at parse time but do not otherwise affect rendering. Additionally you may call these functions anywhere a Float Function is allowed, even during parsing. The syntax is identical to Float Expressions, however, only float functions that apply to float values may be used. Excluded are for example <code><!--<linkto "strlen">strlen</linkto>--->[[Reference:Numeric Expressions#Functions|strlen]]</code> or <code>[[Reference:Numeric Expressions#Functions|:vlength|vlength]]</code>. You find a full list of supported float functions in the syntax definition below.</p> | ||
Line 136: | Line 137: | ||
logarithms and their inverse (powers) are slow to compute both are provided...</p> | logarithms and their inverse (powers) are slow to compute both are provided...</p> | ||
− | {{#indexentry:Functions, vs. macros | + | {{#indexentry:Functions, vs. macros}} |
+ | {{#indexentry:Macros, vs. functions}} | ||
==Functions and Macros== | ==Functions and Macros== | ||
<p>You can use macros in functions, but the macros will be called only once | <p>You can use macros in functions, but the macros will be called only once | ||
Line 159: | Line 161: | ||
</pre> | </pre> | ||
− | {{#indexentry:Functions, user-defined, float | + | {{#indexentry:Functions, user-defined, float}} |
+ | {{#indexentry:Float, functions, user-defined}} | ||
==Declaring User-Defined Float Functions== | ==Declaring User-Defined Float Functions== | ||
Line 222: | Line 225: | ||
parameter names.</p> | parameter names.</p> | ||
− | {{#indexentry:Functions, user-defined, vector | + | {{#indexentry:Functions, user-defined, vector}} |
+ | {{#indexentry:Vector, functions, user-defined}} | ||
==Declaring User-Defined Vector Functions== | ==Declaring User-Defined Vector Functions== | ||
<p>Right now you may only declare vector functions using one of the special | <p>Right now you may only declare vector functions using one of the special | ||
Line 258: | Line 262: | ||
parameter names.</p> | parameter names.</p> | ||
− | {{#indexentry:Functions, user-defined, color | + | {{#indexentry:Functions, user-defined, color}} |
+ | {{#indexentry:Color, functions, user-defined}} | ||
==Declaring User-Defined Color Functions== | ==Declaring User-Defined Color Functions== | ||
<p>Right now you may only declare color functions using one of the special | <p>Right now you may only declare color functions using one of the special |
Revision as of 23:16, 3 May 2016
Some objects allow you to specify functions that will be evaluated while rendering to determine the surface of these objects. In this respect functions are quite different to macros, which are evaluated at parse time but do not otherwise affect rendering. Additionally you may call these functions anywhere a Float Function is allowed, even during parsing. The syntax is identical to Float Expressions, however, only float functions that apply to float values may be used. Excluded are for example strlen
or vlength
. You find a full list of supported float functions in the syntax definition below.
FLOAT: LOGIC_AND [OR LOGIC_AND] OR: | LOGIC_AND: REL_TERM [AND REL_TERM] AND: &REL_TERM: TERM [REL_OPERATOR TERM] REL_OPERATOR: < | <= | >= | > | = | != TERM: FACTOR [SIGN FACTOR] SIGN: + | - FACTOR: MOD_EXPRESSION [MULT MOD_EXPRESSION] MULT: * | / EXPRESSION: FLOAT_LITERAL | FLOAT_IDENTIFIER | FLOAT_FUNCTION | FLOAT_BUILT-IN_IDENT | FUNCTION_IDENTIFIER | ( FLOAT ) | IDENTIFIER | SIGN EXPRESSION FLOAT_FUNCTION: abs( FLOAT ) | acos( FLOAT ) | acosh( FLOAT ) | asin( FLOAT ) | asinh( FLOAT ) | atan( FLOAT) | atanh( FLOAT) | atan2( FLOAT , FLOAT ) | ceil( FLOAT ) | cos( FLOAT ) | cosh( FLOAT ) | degrees( FLOAT ) | exp( FLOAT ) | floor( FLOAT ) | int( FLOAT ) | ln (Float) | log( FLOAT ) | max( FLOAT , FLOAT, ... ) | min( FLOAT , FLOAT, ... ) | mod( FLOAT , FLOAT ) | pow( FLOAT , FLOAT ) | radians( FLOAT ) | sin( FLOAT ) | sinh( FLOAT ) | sqrt( FLOAT ) | tan( FLOAT ) | tanh( FLOAT ) | select( FLOAT , FLOAT , FLOAT [, FLOAT] ) FUNCTION_IDENTIFIER: #local FUNCTION_IDENTIFIER = function { FLOAT } | #declare FUNCTION_IDENTIFIER = function { FLOAT } | #local FUNCTION_IDENTIFIER = function(IDENT_LIST) { FLOAT } | #declare FUNCTION_IDENTIFIER = function(IDENT_LIST) { FLOAT } | #local FUNCTION_IDENTIFIER = function{SPECIAL_FLOAT_FUNCTION} | #local VECTOR_IDENTIFIER = function{SPECIAL_VECTOR_FUNCTION} | #local COLOR_IDENTIFIER = function { SPECIAL_COLOR_FUNCTION } | IDENT_LIST: IDENT_ITEM [, IDENT_LIST] IDENT_ITEM: x | y | z | u | v | IDENTIFIER (Note: x = u and y = v) SPECIAL_FLOAT_FUNCTION: pattern { PATTERN_BLOCK } SPECIAL_VECTOR_FUNCTION: TRANSFORMATION_BLOCK | SPLINE SPECIAL_COLOR_FUNCTION: PIGMENT PATTERN_BLOCK: PATTERN
Note: Only the above mentioned items can be used in user-defined functions. For example the rand() function is not available.
All of the above mentioned float functions are described in the section Float Functions.
Sum and Product functions
|
|
|
|
For both prod
and sum
: i
is any variable name and a
is any expression, usually depending on i
. b
and n
are also any expression.
Note: Even though the following example demonstrates just one usage, both the prod
and sum
functions require a wrapper before use.
#declare factorial = function(C) { prod(i, 1, C, i) } #declare A = factorial(5);
The first parameter is the name of the iteration variable. The second is the initial value expression and the third is the final value expression. Those may not depend on the iteration variable but the iteration variable may still be used inside those two expressions (because it happens to already have been defined) but its value is undefined. The last expression is the actual expression which will be iterated through. It may use any variable in scope.
The scope of an iteration variable is the sequence operation function. That is, a iteration variable is only defined when used inside the sum/prod
function. Of course sum/prod
functions may be nested. However, there is one limit of a maximum of 56 local variable defined simultaneously, which essentially means that in any combination sum/prod
functions cannot be nested deeper than 56 levels.
The iteration variable is incremented by one for each step, but its initial and final value may be any value. The iteration will be continued as long as the iteration value is less or equal to the final value.
Note: Because the iteration value is a floating-point variable, adding one will add a certain bias in a long iterations and thus the floating-point precision will be an issue in such a case and needs to be considered by allowing a reasonable error for the final value!
If the expression to be added has a negative sign it will of course in effect be substracted. Thus changing the sign will allow to generate negative values in the sum function. Equally multiplying by 1/expression
effectively creates a division when used in the prod function.
Obviously to work in the first place the initial value of the result is the neutral element of the operation. That is, a sum calculation starts with 0
and a product calculation starts with 1
just like it is assumed in the sum and product functions in 'regular' math.
It should be noted that mathematically either sum or product are redundant because:
log10(prod(i, b, n, a)) = sum(i, b, n, log10(a))
which implies a sum can be represented as a product and vice versa, observing the usual mathematical constraints of logarithms, of course. However, as logarithms and their inverse (powers) are slow to compute both are provided...
Functions and Macros
You can use macros in functions, but the macros will be called only once when the function is defined, not every time the function is called. You cannot pass function variables to the macros.
You can pass functions to macros, how to do this is best explained by an example:
#macro Foo( Bar, X ) #declare Y = Bar(X); #declare Z = Bar(Y); #end #declare FUNC=function(n){n+2} Foo(FUNC, 1) #debug str(Y,5,5) #debug "\n" #debug str(Z,5,5) #debug "\n"
Declaring User-Defined Float Functions
You declare a user defined function using the #declare
or
#local
directives. By default a function takes three parameters
and you do not have to explicitly specify the parameter names. The default three
parameters are x
, y
and z
. For
example:
#declare foo = function { x + y * z }
If you need fewer or more parameters you have to explicitly specify the parameter list.
Note: The x
and u
as
well as y
and v
keywords are equivalent so you may not specify
both parameter names. You may not specify two or more parameters with the same
name either. Doing so may result in a parse error or undefined function results.
The following are valid functions with parameters:
#declare foo2 = function(x, y, z) { x + y * z } #declare foo3 = function(k1, k2, z, y) { x + y * z + k1 * y + k2 } #declare foo4 = function(h) { h * h + h } #declare foo4 = function(u, v) { x + y * v } //=u + v*v #declare foo4 = function(x, v, z) { u + y * v + z } //=x + v*v + z
Limits:
- The minimum number of parameters per function is 1.
- The maximum number of allowed parameters per function is 56.
- The maximum number of
function
blocks per scene is 1048575. - The maximum number of operators per function is about 200000. Individual limits will be different depending on the types of operators used in the function.
- The maximum depth for nesting functions is 1024.
- The maximum number of constants in all functions 1048575.
Note: Redeclaring functions, directly, is not allowed. The way to do
this is to undef
it first.
There is one special float function type. You may declare a
pattern
function.
Note: The syntax is identical to that of patterns, however, you may not specify colors. Its result is always a float and not a color vector, as returned by a function containing a pigment.
#declare foo = function { pattern { checker } }
Note: The number of parameters of special function types is determined automatically, so you do not need to specify parameter names.
Declaring User-Defined Vector Functions
Right now you may only declare vector functions using one of the special
function types. Supported types are transform
and
spline
functions. For example:
#declare foo = function { transform { rotate <90, 0, 0> scale 4 } } #declare myvector = foo(4, 3, 7); #declare foo2 = function { spline { linear_spline 0.0, <0,0,0> 0.5, <1,0,0> 1.0, <0,0,0> } } #declare myvector2 = foo2(0.7);
Function splines take the vector size into account. That is, a function containing a spline with five components will also return a five component vector (aka a color), a function containing a spline with two components will only return a two component vector and so on.
Note: The number of parameters of special function types is determined automatically, so you do not need to specify parameter names.
Declaring User-Defined Color Functions
Right now you may only declare color functions using one of the special
function types. The only supported type is the pigment
function.
You may use every valid pigment
. This is a very simple example:
#declare foo = function { pigment { color red 1 } } #declare Vec = foo(1,2,3)
An example using a pattern:
#declare foo = function { pigment { crackle color_map { [0.3, color Red] [1.0, color Blue] } } } #declare Val = foo(2,3,4).gray
Note: The number of parameters of special function types is determined automatically, so you do not need to specify parameter names.
Internal Pre-Defined Functions
Several functions are pre-defined. These internal functions can be accessed through
the functions.inc
, so it should be included in your scene. The number of required parameters and what they control are also given in the include
file. See the functions.inc chapter in the Standard Include File section gives more information.