I've added all the options from the Built-in version Tessellation.cginc to the CustomTessellation.hlsl
If you look in CustomTessellation.hlsl, there are 2 more options commented out, for edge length based tessellation (Can get very dense) and the same with culling, which works in theory but I dont know how to properly test that
Original Post 12/2020
In this post I'm going over the most basic tessellated shader in URP.
The setup is actually very similar to the built-in/legacy tessellation but if you're like me and only used it in combination with surface shaders it's a bit more work than that.
The Shader code and HLSL file you need are linked at the bottom
Lets start with the most simple unlit URP code shader from the Unity documentation
It's the equivalent of a vertex/fragment shader you might know from legacy, but a few things are different.
It's a HLSLPROGRAM instead of CGPROGRAM
There's a "RenderPipeline" = "UniversalRenderPipeline" tag
The appdata struct is called Attributes, and the v2f struct is called Varyings.
But luckily the rest is nearly identical
So to add in tessellation we need 3 more functions. Currently it goes
Vertex > Fragment
But we will need
Vertex > Hull > Domain + Second Vertex > Fragment
Very roughly : Take the original vertices, gather data to divide them, divide them, pass divided vertices on again, colorize.
The links at the bottom do a better job of explaining the process, I don't want to copy what they say so please check them out.
We start with the extra vertex struct,
Instead of : POSITION, notice how it says INTERNALTESSPOS
The mesh data of the original vertex struct
Simply passing through the data. This is the function declared in #pragma vertex (TessellationVertexProgram)
The hull program needs all these [UNITY_] parts to know what to do.
After that we do the actual tessellation in patchConstantFunction, as described above the hull program.
It's set up to fade over distance from the camera.
note how the usual _WorldSpaceCameraPos is replaced by GetCameraPositionWS()
Finally we go through the domain program, which goes through the second vertex function.
After Tessellation Vertex
In this second vertex function, we can finally use the tessellated vertices properly, set up here as a noise texture displacing over the whole mesh
The fragment program doesn't change, I've just added (Varyings IN) so we can use the UV map.
Note: I moved the second vertex function, and the domain from the .hlsl to the shader itself so it's a bit clearer where the per-shader parts are. These 2 function are commented out in the CustomTessellation file, you should copy them over to a new shader you make with tessellation :)