How can I change a simple Diffuse shader so that the texture can be displaced along the normal?

Shader "Custom/Diffuse" {
    Properties{
        _Color("Main Color", Color) = (1,1,1,1)
        _MainTex("Base (RGB)", 2D) = "white" {}
    }
        SubShader{
            Tags { "RenderType" = "Opaque" }
            LOD 200

        CGPROGRAM
        #pragma surface surf Lambert

        sampler2D _MainTex;
        fixed4 _Color;

        struct Input {
            float2 uv_MainTex;
        };

        void surf(Input IN, inout SurfaceOutput o) {
            fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color;
            o.Albedo = c.rgb;
            o.Alpha = c.a;
        }
        ENDCG
    }

        Fallback "Legacy Shaders/VertexLit"
}

7157059--856825--5454545.png

Add float3 normal; to your Input struct to store the surface normal into, then you’ll have access to the surface normal through IN.normal in your surf() function.
To store the surface normal in there, you’ll need to add a custom vertex pass.
To do so, first add vertex:vert to your #pragma surface line.
This basically says “For our vertex phase, call the ‘vert()’ function”.
Then you’ll want a barebones vertex function:

//appdata_base contains just position, normal, uv0
//https://docs.unity3d.com/Manual/SL-VertexProgramInputs.html
void vert (inout appdata_base v, out Input o)
{
    UNITY_INITIALIZE_OUTPUT(Input,o);
    o.normal = v.normal;
}

And then you should be good to go to use the IN.normal however you want in your UV calculation. Could even do the adjustment to the UV in your vertex pass first instead of in the frag/surf to save on some calculations.