Unable to convert legacy shader to shader graph

I have this shader which is working in the default render pipeline. basically i am generating ao values for runtime generated blocky voxel mesh and the ao values are passed to the shader as uv1. in the vertex shader the ao value is nomalized and the 4 ao values of the face are passed to surf per vertex where the ao value is interpolated according to uv and applied to albedo

Shader "VloxyEngine/Lit/VertexColorAO" {
    Properties {
        _Glossiness ("Smoothness", Range(0,1)) = 0.0
        _Metallic ("Metallic", Range(0,1)) = 0.0
        _AOColor ("AO Color", Color) = (0,0,0,1)
        _AOCurve ("AO Curve", Vector) = (0.75, 0.825, 0.9, 1.0)
        _AOIntensity ("AO Intensity", Range(0, 1)) = 1.0
        _AOPower ("AO Power", Range(0, 1)) = 1.0
    }
    SubShader {
        Tags { "RenderType"="Opaque" }
        LOD 200
       
        CGPROGRAM
        #pragma surface surf Standard fullforwardshadows
        #pragma vertex vert
        #pragma target 3.0

        struct Input {
            float4 color : COLOR;
            float2 aocoords;
            float4 aovector;
        };

        half _Glossiness;
        half _Metallic;
       
        half4 _AOColor;
        float4 _AOCurve;
        float _AOIntensity;
        float _AOPower;

        float compute_ao(float index) {
            return pow(_AOCurve[index] * _AOIntensity, _AOPower);
        }
       
        void vert (inout appdata_full v, out Input o) {
            UNITY_INITIALIZE_OUTPUT(Input, o);
            o.aocoords = v.texcoord.xy;
            o.aovector = float4(compute_ao(v.texcoord1.x), compute_ao(v.texcoord1.y), compute_ao(v.texcoord1.z), compute_ao(v.texcoord1.w));
        }
       
        void surf (Input IN, inout SurfaceOutputStandard o) {
            float ao1 = lerp(IN.aovector.x, IN.aovector.z, IN.aocoords.x);
            float ao2 = lerp(IN.aovector.y, IN.aovector.w, IN.aocoords.x);
            float ao = lerp(ao1, ao2, IN.aocoords.y);
       
            o.Albedo = lerp(_AOColor.rgb, IN.color.rgb, ao);
            o.Metallic = _Metallic;
            o.Smoothness = _Glossiness;
            o.Alpha = IN.color.a;
        }
       
        ENDCG
    }
    FallBack "Diffuse"
}

Now I tried converting this to shader graph and i don’t understand how to get somthing like the Input struct above, basically pass custom data from vert to surf. Shader graph does have bock context for vertex and fragment shader but i am limited to the types of nodes permitted in those contexts. is there any way I can pass custom data ?

for now i have created this graph, where compute_ao is a subgraph with a custom function node.

Any help would be appriciated

I don’t think there’s a way to pass custom data to vertex / fragment nodes. You’re pretty much stuck with the vertex / fragment nodes provided by Shader Graph.

That being said, have you tried to use the lit material option? With this option, the fragment node has inputs for albedo (base color), alpha, smoothness and metallic, which seems to be what you need in this case? You can change it under graph settings > universal > material. Don’t forget to make sure that the workflow option below is set to metallic.

I am using a lit shader I just removed the nodes I wasn’t using.
if there is no way to pass custom data then I guess I have only 2 options

  • Do the vertex shader calculations (compute_ao) in C# while mesh generation and pass it directly to shader circumventing the need to pass custom v2f data (but this may slow down overall mesh generations as these calculations will happen much faster on the GPU)
  • Write a URP shader, I have seen most people discourage this option and for good reason

Anyway thanks for the help