Basic Tessellation setup in URP

Update 06/2022,
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

Here's the new CustomTessellation.hlsl file : Pastebin Link
and the new BasicTessellation shader file to go with it, a little cleaner : Pastebin Link 

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.

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.

Pre Tessellation

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 :)

Shader Code with comments (You need both!):

Basic Shader : Pastebin Link
CustomTessellation.hlsl(Updated):  Pastebin Link 

Tessellation by Catlikecoding 

How to dynamically tessellate a plane on Unity forums by Mr_Admirals 

Become a member to

Unlock 167 exclusive posts
Be part of the community
Connect via private message