Template:Scripts LanguageBuiltins Functions

From PopcornFX
Jump to navigation Jump to search
Function float int Description
vrand()
Y N random function, returns a random float3 vector 'v' on the unit sphere (ie: a random normal vector uniformly distributed on the sphere's surface)
select(a,b,c) Y Y
returns 'a' or 'b' depending on the value of 'c'

'c' should be the boolean result of a compare operation, or function returning a true / false result. ex: select(float3(0), float3(1,2,3), x <= y); will return float3(1,2,3) if x <= y, otherwise it will return float3(0).

logic:

if (c is true)
  return b;
else
  return a;
iif(c,a,b) Y Y
iif: Inline IF
returns 'a' or 'b' depending on the value of 'c'. Like 'select', but reversed, syntactically closer to the syntax of an 'if/else' block.

'c' should be the boolean result of a compare operation, or function returning a true / false result. ex: iif(x <= y, float3(1,2,3), float3(0)); will return float3(1,2,3) if x <= y, otherwise it will return float3(0).

logic:

if (c is true)
  return a;
else
  return b;
lerp(a,b,t) Y N
lineary blends between 'a' and 'b' based on the value of 't'

't' is an interpolation factor in the $ [0, 1] $ range. when 't' equals 0, 'a' is returned, when 't' equals 1, 'b' is returned. values in between return values between 'a' and 'b'.
ex: lerp(float3(0), float3(1,2,3), 0.5); will return float3(0.5, 1, 1.5).

logic:

return a + t * (b - a);

equivalent to:

return a * (1-t) + b * t;
smoothlerp(a,b,t) Y N
v1.9.0 smoothly blends between 'a' and 'b' based on the value of 't'

't' is an interpolation factor in the $ [0, 1] $ range. when 't' equals 0, 'a' is returned, when 't' equals 1, 'b' is returned. values in between return values between 'a' and 'b'.
ex: smoothlerp(float3(0), float3(1,2,3), 0.5); will return float3(0.5, 1, 1.5).

logic:

return lerp(a, b, smoothstep(0, 1, t));

equivalent to:

return lerp(a, b, 3*t*t - 2*t*t*t);
randsel(a,b)

randsel(a,b,k)

Y Y
NewIcon.png v1.10.0 randomly returns 'a' or 'b'.

the two-argument version of 'randsel' has equal probability to return 'a' or 'b', and calling randsel(a, b); is equivalent to calling randsel(a, b, 0.5);
you can specify a custom probability to get either 'a' or 'b' by using the the three-argument version of 'randsel':
randsel(a, b, 0.1); will have a 10% chance of returning 'b', and a 90% chance of returning 'a'
randsel(a, b, 0.75); will have a 75% chance of returning 'b', and a 25% chance of returning 'a'
etc..
The order of the parameters can be counter-intuitive, but you can think of it like lerp(a,b,k), a value of 'k' close to 0 will return values close to 'a', a value of 'k' close to 1 will return values close to 'b'. Same with randsel(a,b,k), low values of 'k' return 'a' more often, high values return 'b' more often.

logic:

  return select(a, b, rand(0,1) < k);
within(x,lower,upper) Y N
returns 1.0f if 'x' is within the [lower, upper] range, returns 0.0f otherwise.

all the function's arguments can be either scalars, or vectors. if some arguments are vectors, they must have the same dimension. The return value will be a vector as large as the largest input vector.
IE: you cannot call within(float2, float3, float4), but you can call within(float, float, float4) or within(float3, float, float3)


ex:
within(0.5, -1.2, 3.0); will return 1.0f.
within(float3(-2,0,2.5), -1.2, 3.0); will return float3(0.0, 1.0, 1.0).
within(1.5, -1.0, float4(0,1,2,3)); will return float4(0.0, 0.0, 1.0, 1.0).

remap(value, newMin, newMax)

remap(value, oldMin, oldMax, newMin, newMax)

Y Y
v1.8.0

remaps 'value' from the [oldMin, oldMax] range to the [newMin, newMax] range.
all the function's arguments can be either scalars, or vectors. if some arguments are vectors, they must have the same dimension. The return value will be a vector as large as the largest input vector.
IE: you cannot call remap(float2, float3, float4), but you can call remap(float, float, float4) or remap(float3, float, float3)
the version that has no 'oldMin' and 'oldMax' assumes the original range is [0,1]


ex:
remap(0.5, 1.0, 3.0); will return 2.0f.
remap(0.5, 0, 0.5, 1.0, 3.0); will return 3.0f.

all(c) N Y
returns true if ALL elements of vector 'c' are non-zero / not 'false'

'c' can be a boolean result of a compare operator, or any vector. ex:
all(float3(0) < float3(1,2,3)); will return true. all(float3(0) < float3(1,-2,3)); will return false.

logic:

foreach (element e in c)
  if (e == 0)
    return false;
return true;
any(c) N Y
returns true if ANY element of vector 'c' are non-zero / not 'false'

'c' can be a boolean result of a compare operator, or any vector. ex:
any(float3(0) > float3(1,2,3)); will return false. any(float3(0) > float3(1,-2,3)); will return true.

logic:

foreach (element e in c)
  if (e != 0)
    return true;
return false;
rotate(v, axis, angle) Y N
returns the vector 'v' rotated around 'axis' by 'angle'.

'v' and 'axis' are float3 vectors, 'angle' is the angle in radians (can be negative).
ex:
rotate(float3(1,0,0), float3(0,1,0), pi); will return float3(-1,0,0) (rotates float3(1,0,0) along the 'y' axis float3(0,1,0) by 180 degrees ('pi' radians), leading to the opposite vector float3(-1,0,0). rotate(float3(1,0,0), float3(0,1,0), pi/2); will return float3(0,0,1).

deg2rad(v)

rad2deg(v)

Y N
NewIcon.png v1.10.0

deg2rad(v) converts the input angle from degrees to radians.
deg2rad(90); will return pi/2.
deg2rad(123.456); will return 2.1547137.


rad2deg(v)converts the input angle from radians to degrees.
rad2deg(pi/2); will return 90.
rad2deg(1.23456); will return 70.735.

safe_normalize(v)

safe_normalize(v, vz)
safe_normalize(v, vz, epsilon)

safe_fast_normalize(v)
safe_fast_normalize(v, vz)
safe_fast_normalize(v, vz, epsilon)

Y N/A
v1.5.5+ / v1.6.0

Normalizes the input 'v' vector and returns the resulting unit-vector. Unlike the 'normalize' and 'safe_normalize' builtins, these safe versions check for null vectors.
This will prevent normalizing a null vector and getting an Infinity or NaN vector in return.
Works on any vector dimensions.
ex:
safe_normalize(vector3); returns normalize(vector3), but if length(vector3) < 1.0e-8, returns float3(0,0,0).
safe_normalize(vector3, float3(0,1,0)); returns normalize(vector3), but if length(vector3) < 1.0e-8, returns float3(0,1,0).
safe_normalize(vector3, float3(0,1,0), 1.0e-6); returns normalize(vector3), but if length(vector3) < 1.0e-6, returns float3(0,1,0).

safe_normalize(vector3)

is equivalent to:

select(normalize(vector3), float3(0), length(vector3) < 1.0e-8);

logic:

if (length(v) < epsilon)
  return vz;
else
  return normalize(v);
noise(t)

fast_noise(t)

Y N/A
v1.6.0

evaluates a coherent noise field. 't' can be a float, float2, float3, or float4 cursor. All functions return a single float value in the [-1,1] range.
noise() computes a high quality simplex-noise.
fast_noise() computes a slightly lower quality, but faster, noise.

ex:
noise(LifeRatio); will sample a 1D noise
noise(uv * 100); will sample a 2D noise
noise(Position); will sample a 3D noise
noise(float4(Position, scene.Time)); will sample a 4D noise

float3suf(side, up, forward)

float3suf(...)
float3sfu(side, forward, up)
float3sfu(...)

Y N
v1.8.2

NewIcon.png v1.10.0 (SFU permutation)
Takes the side, up, and forward components and permutes/swizzles them based on the current Axis-System.

example:

 float3suf(0, 18, 0);
  • Y-Up axis-system: float3(0, 18, 0);
  • Z-Up axis-system: float3(0, 0, 18);

example:

 float3 vec = float3(1, 2, 3);
 res = float3suf(vec);
  • Y-Up axis-system: res = vec; (no changes)
  • Z-Up axis-system: res = vec.xzy; (so: float3(1, 3, 2))
isfinite(v)

isinf(v)
isnan(v)

Y N
NewIcon.png v1.10.0

Useful to detect infinite or invalid values.

  • isfinite(v) returns true if 'v' is a finite value, false if not.
isfinite(42);     --> true
isfinite(1.0/0.0);--> false
isinf(0.0/0.0);   --> false
  • isinf(v) returns true if 'v' is an infinite value, false if not (either finite or NaN).
isinf(42);        --> false
isinf(1.0/0.0);   --> true
isinf(0.0/0.0);   --> false
  • isnan(v) returns true if 'v' is a NaN value (NaN = "Not a Number"), false if not.
isnan(42);        --> false
isnan(1.0/0.0);   --> false
isnan(0.0/0.0);   --> true

This function can be used to check the return values of some functions that return infinite values as a way to report en empty result. For example, spatial queries:

float3 p = spatialLayers.MyLayer.Position.closest(Position);
Position = select(Position, p, all(isfinite(p)));
blackbody(t)

fast_blackbody(t)

Y N
NewIcon.png v1.10.0

returns the normalized RGB chromaticity color of the emission spectrum of a blackbody at the specified temperature

The input value should be a temperature in degrees kelvin. For example, 800 will give a red color, 3000 will give an orange/yellow color, 5000/6000 will give a white color, and higher temperatures will give a blue color. RGB colors returned are in linear space, not in sRGB space.
Can be very useful for 'physically correct' lava/fire effects.

The 'fast' version uses a different algorithm (a polynomial fit on the final RGB curves) than the regular version (which uses a polynomial fit of the chromaticity-space planckian locus), is roughly twice faster, but much less precise (although it's probably fine for most applications).

Here's the RGB comparison between the regular and fast versions:
blackbody() vs fast_blackbody()


The two are virtually identical. Only when plotting the actual RGB curves you start seeing a difference:

blackbody() : Planckian locus, polynomial fit in chroma space fast_blackbody() : polynomial fit in RGB space relative error between blackbody() and fast_blackbody(), magnified 10 times
blackbody() fast_blackbody() Rel. error times 10