Upgrade Shader to URP

I was working in a project without URP, and now I update the project and I don’t know how to upgrade a custom shader that I created. This is the shader:

Shader "Custom/Terrain" {
    Properties {
        testTexture("Texture", 2D) = "white"{}
        testScale("Scale", Float) = 1

    }
    SubShader {
        Tags { "RenderType"="Opaque" }
        LOD 200
       
        CGPROGRAM
        // Physically based Standard lighting model, and enable shadows on all light types
        #pragma surface surf Standard fullforwardshadows

        // Use shader model 3.0 target, to get nicer looking lighting
        #pragma target 3.0

        const static int maxLayerCount = 8;
        const static float epsilon = 1E-4;

        int layerCount;
        float3 baseColours[maxLayerCount];
        float baseStartHeights[maxLayerCount];
        float baseBlends[maxLayerCount];
        float baseColourStrength[maxLayerCount];
        float baseTextureScales[maxLayerCount];

        float minHeight;
        float maxHeight;

        sampler2D testTexture;
        float testScale;

        UNITY_DECLARE_TEX2DARRAY(baseTextures);

        struct Input {
            float3 worldPos;
            float3 worldNormal;
        };

        float inverseLerp(float a, float b, float value) {
            return saturate((value-a)/(b-a));
        }

        float3 triplanar(float3 worldPos, float scale, float3 blendAxes, int textureIndex) {
            float3 scaledWorldPos = worldPos / scale;
            float3 xProjection = UNITY_SAMPLE_TEX2DARRAY(baseTextures, float3(scaledWorldPos.y, scaledWorldPos.z, textureIndex)) * blendAxes.x;
            float3 yProjection = UNITY_SAMPLE_TEX2DARRAY(baseTextures, float3(scaledWorldPos.x, scaledWorldPos.z, textureIndex)) * blendAxes.y;
            float3 zProjection = UNITY_SAMPLE_TEX2DARRAY(baseTextures, float3(scaledWorldPos.x, scaledWorldPos.y, textureIndex)) * blendAxes.z;
            return xProjection + yProjection + zProjection;
        }

        void surf (Input IN, inout SurfaceOutputStandard o) {
            float heightPercent = inverseLerp(minHeight,maxHeight, IN.worldPos.y);
            float3 blendAxes = abs(IN.worldNormal);
            blendAxes /= blendAxes.x + blendAxes.y + blendAxes.z;

            for (int i = 0; i < layerCount; i ++) {
                float drawStrength = inverseLerp(-baseBlends[i]/2 - epsilon, baseBlends[i]/2, heightPercent - baseStartHeights[i]);

                float3 baseColour = baseColours[i] * baseColourStrength[i];
                float3 textureColour = triplanar(IN.worldPos, baseTextureScales[i], blendAxes, i) * (1-baseColourStrength[i]);

                o.Albedo = o.Albedo * (1-drawStrength) + (baseColour+textureColour) * drawStrength;
            }

       
        }


        ENDCG
    }
    FallBack "Diffuse"
}

I read that I have to change the #pragma in line 13 to surface surf StandardLit fullforwardshadows and the inout in the void surf in line 53 to SurfaceOutputStandardLit but it doesn’t work.

How can I fix this?

It might be best to just create a new Opaque material in URP, open and copy the shader code to a new file and see if you can adjust anything you need there. One thing I noticed is the missing “RenderPipeline” = “UniversalPipeline” tag:

        Tags
        {
            "RenderType" = "Opaque"
            "RenderPipeline" = "UniversalPipeline"
            "UniversalMaterialType" = "Lit"
            "IgnoreProjector" = "True"
        }
        LOD 300

Hi, surface shader is not compatible with URP (and HDRP)'s lighting system, you may want to recreate it as vert() and frag() shader or in a shader graph.

Export the surface shader code to vertex fragment shader and use URP libraries to replace the lighting part.

These are easier said than done though.

Another option is export a base URP shader from Shader Graph and adapt the changes there.