Can't define function in hlsl on custom shader node.

I am trying to use a function in a custom shader in my post processing material, but whenever I try to compile it says

The shader code is:

float4 Kuwahara(float2 uv2){
    //float version of the radius
    float r = float(radius);

    //array of the averages for each pixel region
    float3 avg[4];
    avg[0] = float3(0.0f, 0.0f, 0.0f);
    avg[1] = float3(0.0f, 0.0f, 0.0f);
    avg[2] = float3(0.0f, 0.0f, 0.0f);
    avg[3] = float3(0.0f, 0.0f, 0.0f);




    //array of the standard deviaitons for each pixel region
    float3 std[4];
    std[0] = float3(0.0f, 0.0f, 0.0f);
    std[1] = float3(0.0f, 0.0f, 0.0f);
    std[2] = float3(0.0f, 0.0f, 0.0f);
    std[3] = float3(0.0f, 0.0f, 0.0f);


    //the offsets for each reigon to sample over
    float2 offs[4];
    offs[0] = float2(-r, 0.0f);
    offs[1] = float2(-r, 0.0f);
    offs[2] = float2(0.0f, -r);
    offs[3] = float2(0.0f, 0.0f);


    //position and color holders
    float2 p;
    float3 col;

    //loop through each region
    for(int i = 0; i < 4; i++){

    //for each x
    for(int x = 0; x <= radius; x++){
        
        //for each y
        for(int y = 0; y <=radius; y++){
            
            //the positon is each pixel within each region i
            p = float2(float(x), float(y)) + offs[i];
            
            //the uv2 position of the pixel to sample is the base uv2 plus the pixel offset
            float2 uvp = uv2 + (p / iResolution);
            
            
            //sample the texture at that position
            col = SceneTextureLookup(uvp, 14, false).rgb;
            
            
            //add in the color to the average color of the region
            avg[i] += col;
            
            //add the standard deviation of this color from the region color
            std[i] += col * col;
            
        }
    }

    }



    //the total number of pixels that were sampled
    float n = pow(r + 1.0f, 2.0f);



    //holder for the lowest value
    float minV = 1.0f;

    //holder for the standard deviation of the corresponding lowest value
    float stdf;

    for(int i = 0; i < 4; i++){

    //make the average colors actually averaged (the are simply sums right now)
    avg[i] /= n;

    //calculate standard deviation according to standard deviation formula
    std[i] = abs((std[i] / n) - (avg[i] * avg[i]));

    //sum the standard deviation of each rgb value for this region
    stdf = std[i].r + std[i].g + std[i].b;

    //if this region's standard deviation is the lowest then use it
    if(stdf < minV){
        
        //record this standard deviation
        minV = stdf;
        
        //select the value with the lowest standard deviation
        col = avg[i];
    }

    }



    return col;


}


float4 main(){
    float2 off = 1.0f / iResolution;

    float2 right = float2(off.x, 0.0f);
    float2 up = float2(0.0f, off.y);



    float4 c1 = Kuwahara(uv);
    float4 c2 = Kuwahara(uv + right);
    float4 c3 = Kuwahara(uv + up);

    return (c1 - c2) + (c1 - c3);
}




main();

Why is this happening?

It is not really documented clearly.
If you are using a custom HLSL node in a material graph blue print…
Your HLSL code is copied into ANOTHER generated HLSL code module, this is done because some boiler plate code is needed so that you don’t have to deal with that mess yourself…

A temporary “Material.ush” file gets auto generated for every custom HLSL node you make. And your code is inserted into it.

For you to use functions you have to wrap the functions into a struct. Like this…

PLACE YOUR Custom Functions INTO THIS STRUCTURE
struct CustomFunctions // ANY NAME IS SUITABLE
{  
    // PLACE ANY OTHER "GLOBAL" VARIABLES HERE
    // PLACE ANY OTHER FUNCTIONS HERE AS WELL
float AVariable1;    
float2 AVariable2;    // etc...

void Foo1()
{
    ......code ...
}

void Foo2()
{
    ......code ...
}

// etc etc etc

float4 main(***your params***)
 {
  
return fragColor;
}

};

// THIS PART BELOW IS *NOT* WRAPPED INTO THE ABOVE STRUCT
CustomFunctions CF;
float4 fragColor = CF.main(* named inputs to your shader *);
return fragColor;

If your custom node had these 3 named input slots…
Then you could call your main function like this…
float4 fragColor = CF.main(UV, Timer, BufferA);

1 Like