Implementing new type in Fuse to use it also in sdsl shaders

Hello everyone!
Let’s say for learning purposes I wanted to write my own struct type to use in Fuse for raymarching.
This struct I called myRay. I wrote it in c# using instructions from the old tutorial " Turning a .NET library into a VL library" from Node Institute. I built the solution and then added the file myRay.dll to dependencies to my patch in VVVV.

So far so good, I can see my myRay type while patching in vvvv. Then I patch CustomFunction (my own kind of raymarch patch) and there I need to use some other CustomFunction (say, called Shading) where I need to use myRay type as function parameter.

Of course I also wrote code templates as sdsl files for two functions.
Actually I did it a while ago and it used to work. My problem is that now after a while I returned to this project and found out that the code does not compile. It gives me an error: Could not compile shader. See error messages.[shaders\Shader_395559997.sdsl(27,31)]: Error: E0005: Unable to find a suitable overloaded method [Shade13281]

so what do I do wrong?
There are some screenshots to make it clear, and also final shader code.



shader Shader_813944945 : VS_PS_Base, Texturing, FuseRayMarch2, FuseCommonSDF, myFuseCommonTypes
{
    cbuffer Inputs{

        [Link("input_13319")]
        stage float3 input_13319;

        [Link("input_13322")]
        stage float3 input_13322;

        [Link("input_13325")]
        stage float3 input_13325;

        [Link("input_13345")]
        stage myRay input_13345;

    }



    float SDF13337(float3 arg_arg_0){
        float3 result_13330 = input_13319 - input_13322;
        float3 result_13334 = input_13325 * float3(0.5,0.5,0.5);
        float result_13337 = fBox(result_13330, result_13334);

        return result_13337;
    }

    float4 SHADE113393(myRay arg_input_13345){
        float4 result_13393 = Shade13391(arg_input_13345);

        return result_13393;
    }

    float4 Shade13391()
    {
    
        float4 color = float4(1,0,1,1);
        return color;
    }
    
    


    
    float SDF(float3 p) // should be override unless it's the first imp.  Gets called by the other functions
    {
    	return SDF13337(p);
    }
    
    float4 RayMarcher13396()
    {
    	float2 uv = streams.TexCoord;
    	float3 rd = normalize(mul(float4(mul(float4((uv.xy*2-1)*float2(1,-1),0,1),ProjectionInverse).xy,-1,0),ViewInverse).xyz);
    	float3 ro = ViewInverse[3].xyz;
    
    	//sray =  makemyRay(ro, rd);
    	float iter = 0;
    	float4 color = float4(0,0,0,0);
    	float4 f = 0;
    	int maxIter = 180.;
    
    	//float3 z = marchRayDefualt2(ray, f, iter, uv, float2(0.01,100), maxIter);
        //if(z.x > 0. && z.x < 500)
    
        {
    	  color = 1;//SHADE113393(ray);
    	}
    	return color; 
    }
    
    
    







    stage override void VSMain()
    {
        float4 result_13367 = streams.Position * float4(2,2,0,1);

        streams.ShadingPosition = result_13367;

    }

    stage override void PSMain()
    {
        float4 result_13398 = RayMarcher13396();

        streams.ColorTarget = result_13398;

    }
};

And just cleaned the code to make it as simple as possible, so it might look like it does not make much sense :)

From what I understand, you are mixing C#, which is CPU code, with SDSL, which is GPU code. You can’t use C# types in a shader, they are from different worlds.

What you probably want is a *.sdsl file that contains your GPU struct and then include that file as a base class for other shaders that use your new SDSL struct.

And unfortunately, you cannot use custom structs as the type for shader input pins, they have to be primitive types and you need a method that converts your struct into a float4, for example.

But you can use “blittable” types, which is a C# struct MyRayCSharp that can be stored as an array with consecutive memory layout and use an Immutable or DynamicBuffer to upload a sequence of them (could also be just one) to the GPU and read it in the shader as a StructuredBuffer<MyRaySDSL>. If they match in byte size, it saves you a bit of conversion code.

So in your case, it would look like

    [Link("input_13345")]
    stage StructuredBuffer<myRay> input_13345;

in the shader, instead of what you have right now.

1 Like

Thank you very much, was very helpful