Material: Using common functions from within custom expression nodes

Hello,

for example: I have a custom function expression with for-loops and i want to call sub-functions.
This wasn’t possible because custom expression code is wrapped inside a function and hlsl doesn’t allow functions within functions.

So I searched some time and found solutions which work on former versions. (before 4.16)
Unfortunately, these tricks doesn’t work anymore.

But i found a new solution i want to share.

Goal: Write a custom voronoi function for a procedural generated texture. This function used some other custom function which has to be defined before the voronoi function.



float2 n = floor(x);
float2 f = frac(x);
//----------------------------------
// first pass: regular voronoi
//----------------------------------
float2 mg, mr;
float md = 8.0;
for (int j = -1; j <= 1; ++j)
for (int i = -1; i <= 1; ++i) {
  float2 g = float2(float(i), float(j));
  float2 o = hash2(n + g);
  float2 r = g + o - f;
  float d = dot(r, r);
  if (d < md) {
    md = d;
    mr = r;
    mg = g;
  }
}
//----------------------------------
// second pass: distance to borders
//----------------------------------
md = 8.0;
for (int j = -2; j <= 2; ++j)
for (int i = -2; i <= 2; ++i) {
  float2 g = mg + float2(float(i), float(j));
  float2 o = hash2(n + g);
  float2 r = g + o - f;
  if (dot(mr - r, mr - r) > 0.00001) {
    md = min(md, dot(0.5 * (mr + r), normalize(r - mr)));
  }
}
return float3(md, mr);


As you can see this function is using “hash2”, another custom function…

I create a “incCommon” Material Function:


The code which contains the custom “hash2” function is the following:



#ifndef _INC_COMMON_
#define _INC_COMMON_

  return dummy;
}

float foo1()
{
  return 123.45;
}

float foo2()
{
  return 0.0;
}

float3 hash2(float2 p)
{
  float3 p3 = frac(float3(p.xyx) * .1031);
  p3 += dot(p3, p3.yzx + 33.33);
  return frac((p3.x + p3.y) * p3.z);

#else

  return dummy;
#endif


As you can see now, the last common function “hash2” does not write the closing bracket. Also I close the Bracket in the case, the symbol INC_COMMON isn’t defined. In the #else branch i only return the dummy float.

All i have to do now is an additional dummy parameter in my voronoi function:

Each custom material expression which is using any of my cummon functions gets this additional dummy parameter.

:eek:

That’s pretty awesome if it *does *work. I always trip up when doing custom stuff like this, and forget my solutions after a bit. Thanks for sharing!