Mastering Tessellation Shaders in Unity! Easy LoD, Curved Triangles, Height Maps | Game Dev Tutorial

Поділитися
Вставка
  • Опубліковано 6 сер 2024
  • ✔️ Tutorial tested in Unity URP 2020.3, 2021.3
    Hi! Tessellation shaders are advanced shaders which can subdivide triangles in a mesh, creating new vertices. You can move these around for a variety of cool effects! This tutorial aims to give you a deep understanding of tessellation shaders in Unity by first explaining how to write your own and then showcasing several algorithms which use them. Some effects include advance culling, dynamic level of detail, curved triangles, smoothed silhouettes, height map rendering, and procedural meshes.
    📚 If you prefer reading, check out the written version of this tutorial here:
    ► / mastering-tessellation...
    👋 Subscribe for weekly game development videos!
    ► ua-cam.com/users/nedmakesgam...
    👑 Join my Patreon to watch videos early, download all project files, vote on future topics, and more! Thank you so much!
    ► / nedmakesgames
    🔗 Visit my website for a searchable list of tutorials!
    ► nedmakesgames.github.io
    2️⃣ 2nd Channel ► / nedmakesgames2
    🔴 Twitch ► / nedmakesgames
    🐦 Twitter ► / nedmakesgames
    🎮 Discord ► discordapp.com/invite/ubxSVBK
    📸 Instagram ► / nedmakesgames
    👽 Reddit ► / nedmakesgames
    🎶 TikTok ► / nedmakesgames
    ☕ Ko-fi ► ko-fi.com/nedmakesgames
    💻 Script reference:
    ► Tessellation factors simple shader: gist.github.com/NedMakesGames...
    ► Complete tessellation sample shader: gist.github.com/NedMakesGames...
    ⏲️ Timestamps:
    0:00 Intro
    0:46 Tutorial scope
    2:10 What is tessellation?
    3:32 Anatomy of a tessellation shader
    7:15 The hull function
    9:03 The patch constant function
    10:11 The domain function
    11:05 Tessellation factors
    12:57 Partitioning modes
    13:59 Optimizing with culling
    14:29 Frustum culling
    15:37 Winding/backface culling
    17:01 Culling tolerance
    17:31 Dynamic tessellation factors
    19:09 Screen space factors
    19:56 Camera depth factors
    20:45 Mesh data factors
    21:39 Deformed patches factors
    22:20 Curved triangles and smoothed silhouettes
    23:10 Phong tessellation
    24:52 Refining models for curved triangles
    25:46 PN triangles
    28:47 Quadratic normal interpolation
    31:18 Height map displacement
    32:45 Normals from height maps
    34:24 Procedural height maps
    36:08 Wrap up and credits
    🎖️ Credits, references and further reading:
    • Lee Rosevere: Music for Podcasts - leerosevere.bandcamp.com/
    • Austin Newman: Transition woosh - austinmakesfilms.sellfy.store...
    • Samcro spm: 3D Sword and Shield Game Ready model - www.turbosquid.com/3d-models/...
    • SHULDYAKOV: 3D model Cat Low Polygon Art Farm Animal Free VR / AR / low-poly - www.turbosquid.com/3d-models/...
    • Lennart Demes: Fabric 060 - ambientcg.com/view?id=Fabric060 and Rocks 022 - ambientcg.com/view?id=Rocks022
    • Iñigo Quilez: Noise - Gradient - 3D - Deriv - www.shadertoy.com/view/4dffRH
    • Scratchapixel: Perlin Noise - www.scratchapixel.com/lessons... and Geometry - www.scratchapixel.com/lessons...
    • Freya Holmér: The Beauty of Bézier Curves - • The Beauty of Bézier C...
    • kjpargeter: Detailed wireframe terrain landscape in black and white - www.freepik.com/free-vector/d...
    • OpenClipart-Vectors: Wireframe Human Head - pixabay.com/vectors/head-wire...
    • CatLikeCoding: Flat and Wireframe Shading, Tessellation, and Surface Displacement - catlikecoding.com/unity/tutor...
    • Alex Vlachos, Jörg Peter, Chas Boyd, Jason L. Mitchell: Curved PN Triangles - alex.vlachos.com/graphics/Cur...
    • Tamy Boubekeur, Marc Alexa: Phong Tessellation - www.klayge.org/material/4_0/Ph...
    • Alan Wolfe: Bézier Triangles - blog.demofox.org/2019/12/07/b...
    • Fabian Giesen: View frustum culling - fgiesen.wordpress.com/2010/10...
    #GameDev #IndieDev #Unity
  • Ігри

КОМЕНТАРІ • 75

  • @NedMakesGames
    @NedMakesGames  2 роки тому +11

    Hi everyone! Thanks again for watching! Again, if you prefer written tutorials, I have an article version here: nedmakesgames.medium.com/mastering-tessellation-shaders-and-their-many-uses-in-unity-9caeb760150e
    The script for this video was difficult to write since there was just so much to cover! It was fun experimenting with tessellation, so I hope you enjoy it too. What do you plan to do with it?

    • @hristoborisov3713
      @hristoborisov3713 2 роки тому

      Hi im extremely new to shader code and was wondering how to add smoothness maps to your shader, thank you for providing this amazing sample!!! it works great other than missing smoothness

    • @NedMakesGames
      @NedMakesGames  2 роки тому

      @@hristoborisov3713 The easiest way would be to add another texture to the shader and sample it in the fragment function, along with base color. Then, you can set the smoothness in the SurfaceData struct.
      If you need a refresher about how to work with textures, check out this video which goes over it (towards the end of the video): ua-cam.com/video/KVWsAL37NGw/v-deo.html

    • @hristoborisov3713
      @hristoborisov3713 2 роки тому

      @@NedMakesGames omg thank you so much, I was able to add a float slider for smoothness thanks to your hlsl urp video!!! ty

    • @hristoborisov3713
      @hristoborisov3713 2 роки тому

      @@NedMakesGames also, fog doesn't work for some reason, looking through the code i see you have the fog and vertex lighting in one float4 and everything seems ok but fog doesn't show up ;/
      tried changing float4 to half4 and the fogfactor and vertexlight to half and half3 but still no luck, no compiling errors tho
      I think its because the shader is set to not cast shadows and unity's fog doesn't apply objects that don't cast shadows

    • @NedMakesGames
      @NedMakesGames  2 роки тому

      ​@@hristoborisov3713 I think I actually made an error and forgot to call MixFog after UniversalFragmentPBR! Try this:
      color = UniversalFragmentPBR(lightingInput, surfaceInput);
      color.rgb = MixFog(color.rgb, lightingInput.fogCoord);
      return color;

  • @GreenCream
    @GreenCream 2 роки тому +2

    this is the best age for making video games when someone like you researches & shares their findings online with so much care. making every technique feasable for indie devs. 1000 stars for you ned, i hope you can keep doing this forever.

    • @NedMakesGames
      @NedMakesGames  2 роки тому +1

      Thank you, that's really nice of you to say! I enjoy making these, so I don't plan to stop anytime soon!

  • @vildauget
    @vildauget 2 роки тому +16

    This is pure gold, Ned - the subject, the effort and the tutorial itself, you've come such a long way! Congratulations on understanding enough of tessellation shaders to make such a pro tutorial, and thank you so much for the time and work you've put into this to share it with the rest of us! Personally I only understand what it can do at this point, and will need to figure out how to use hybrid renderer with hlsl first, but I really hope to be open all these doors one day.

    • @NedMakesGames
      @NedMakesGames  2 роки тому +3

      Thank you for the kind words, very nice of you to say! I know tessellation shaders are pretty esoteric, so I hope to make them easier for people to use!
      I would also like to use the hybrid renderer some more. Connecting up with entities is really useful!

  • @DanielKierkegaardAndersen
    @DanielKierkegaardAndersen 2 роки тому +10

    This seems like the definitive guide to tesselation! Thank you so much! :3 - Regards a Unity Employee :P

    • @NedMakesGames
      @NedMakesGames  2 роки тому +2

      Oh wow, that means a lot! Thank you for your hard work!

  • @ParkingLotStudioGames
    @ParkingLotStudioGames Рік тому +2

    "No shader graph in this tutorial" earned you a sub here and on patreon instantly

    • @NedMakesGames
      @NedMakesGames  Рік тому

      Hey, thank you very much for the support! I've been leaning into non-node-based programming lately, so I hope you enjoy the tutorials.

  • @TheUncutAngel
    @TheUncutAngel 2 роки тому +1

    I'm not even gonna use this and I'm still gonna give this video a like. Lol. The quality of your tutorials went form 100 to 1000 real quick. Awesome demonstration.

    • @NedMakesGames
      @NedMakesGames  2 роки тому

      Thank you! I worked really hard on the visualizations this time around and was hoping the video would be entertaining in it's own right. Glad to hear that paid off!

  • @alejmc
    @alejmc 2 роки тому +1

    Wow, totally subbed and queued some of your other videos, namely the compute shader ones.
    Just half-ways in but it just finally dawned onto me that the hull/domain shaders are a fine way to be able to do operations on an vertex while having information about the others thanks to the ‘patch’ concept that groups 3 vertices! The last couple of years I have been avoiding tessellation shaders for now reason and working around that basic vertex shader constraint.

    • @NedMakesGames
      @NedMakesGames  2 роки тому +1

      Thank you, I'm glad to hear that!
      Yeah! That's a cool way to get triangle data without using a geometry shader. It can be pretty powerful.
      Tessellation is pretty intimidating, so I'm happy that this tutorial is making them a little more approachable.

  • @OdemGeek
    @OdemGeek 2 роки тому +3

    Amazing video. It was nice to watch your streams.

    • @NedMakesGames
      @NedMakesGames  2 роки тому +1

      Thank you! I’m glad to hear you like the streams! Taking a small break this week, but they’ll resume Monday.

  • @kolsuzgame7784
    @kolsuzgame7784 2 роки тому +1

    im working on Unity Water Systems tessellation shaders. And NMG post a video at the right time! Thanks!

    • @NedMakesGames
      @NedMakesGames  2 роки тому

      Oh! I hope it goes smoothly for you! Thank you for watching!

  • @BeamNgPro
    @BeamNgPro 2 роки тому +1

    Great tutorial!

    • @NedMakesGames
      @NedMakesGames  2 роки тому

      Thank you for watching! I appreciate it!

  • @ArtificialDjDAGX
    @ArtificialDjDAGX Рік тому +1

    Thank you a thousand times for creating this video and the article that goes through everything more in-depth! It has helped a ton with understanding what to do for phong tessellation, as aside from your article and video, and the paper that introduced the technique, there's no info anywhere about how to implement it!
    Though even with that help, I am in need of some serious help. Even if I use effectively the exact same code as you for the phong tessellation or PN Triangles (I'm working solely with direct3d, no help with stuff from the unity engine), I don't get any rounding of objects at all.
    I'm trying to turn an icosphere (from blender) into a sphere using phong tessellation or PN Triangles, but at best I can get it to look like a popcorn, or an inverted popcorn, otherwise it just looks like a completely unmodified icosphere.
    For the phong tessellation, I don't get any change at all, no matter what I set the shape factor to, and for the PN Triangles, the way I can change the way the object looks is by varying the multiplier for bezierpoints[6], because with a multiplier of 6 I only get the pure icosphere.
    Edit: I ended up finding the issue, the model didn't have normals that allowed for curving, as they were orthogonal to the triangle faces.

  • @hristoborisov3713
    @hristoborisov3713 2 роки тому +1

    this is free! amazing, you are a blessing

    • @NedMakesGames
      @NedMakesGames  2 роки тому

      Hi! Glad you enjoy it, thanks for watching!

  • @john-petercomitis8638
    @john-petercomitis8638 2 роки тому

    Holy shit man Thank you so much for this you absolute Genius!

  • @chris.davidoff
    @chris.davidoff 2 роки тому +3

    Your stuff is unbelievably great!! Thank you so much. I'm thinking now, how could one tesselate and delete faces (I'm thinking a space ship having bullet/laser holes dynamically put into it) hmmmm also: subbed!! I can't wait to see what's next

    • @NedMakesGames
      @NedMakesGames  2 роки тому

      Thank you, I really appreciate that!
      That sounds like an interesting challenge! You can definitely remove original triangles from the mesh by setting tessellation factors to zero. You might be able to remove tessellated sections by setting a vertex's clip space position to NaN in the domain function, but I'm not sure how that would turn out.

  • @CaptainJeoy
    @CaptainJeoy 2 роки тому

    This is gold!

    • @NedMakesGames
      @NedMakesGames  2 роки тому +1

      Glad to help out, thank you for watching!

  • @shubhrojyotikabiraj8322
    @shubhrojyotikabiraj8322 Рік тому +1

    Hey there is no Metallic/Smoothness/AO map in the NedMakesGames_TessellationSample.hlsl shader. It was in the video when you show it in terrain.

  • @hibiscusbear
    @hibiscusbear 2 роки тому

    marvelous!

  • @elmareschlauer1817
    @elmareschlauer1817 2 роки тому +1

    Great tutorial again!
    From what I understand, tesselation hardware is not supported on Metal. We are now supposed to use compute shaders for that now. It would be great to have a tutorial that explains how to do that. I am especially interested in how it would be possible to split edges of arbitrary length so that they are roughly the same length. This would be really useful together with the grass shader. So that the grass density is more even and can be adjusted by the user interactively. I have been trying to wrap my head around doing this in compute shaders, but those are still a bit over my head.

    • @NedMakesGames
      @NedMakesGames  2 роки тому

      Hey! I'm pretty sure, at least in newer Metal versions, tessellation shaders are supported (although they are implemented using compute shaders beneath the hood).
      I almost extended this video to cover tessellation using compute shaders. The math to completely replicate it is not super simple. If all you want to do is subdivide triangles though, it's not tough:
      Create a list of triangles.
      Pop a triangle off the list.
      Split each triangle edge in half, and create four new triangles in a "triforce" pattern.
      Add these new triangles to the list.
      You can keep running this until you get as many subdivisions as you need. In a compute shader, I would just create two structured buffers for triangles. Have your compute shader run the above algorithm to subdivide each triangle once. Then, clear the "origin" buffer, switch the buffers so the divided triangles are the new origin buffer, and dispatch the compute shader again.

    • @elmareschlauer1817
      @elmareschlauer1817 2 роки тому

      @@NedMakesGames Thanks for the reply!
      I am not sure how I would combine a tesselation shader for the tesselation of the source mesh with a compute shader for creating the grass blades.
      The other issue is that I want to only subdivide those edges that are longer than a certain length to make the grass distribution somewhat even, even on a mesh that is not designed for the purpose and has edges of varying lengths or triangles that are very long and thin. For that I would not know beforehand how many triangles I would get out after the subdivision...
      Hope that makes sense.

    • @NedMakesGames
      @NedMakesGames  2 роки тому

      @@elmareschlauer1817 Oh yeah! That does complicate things. You will need to keep count of triangles in the destination mesh. Decide whether to subdivide a triangle based on it's edge lengths and insert the triangles into the next free space in the mesh. Increment the triangle count by 4 using InterlockedAdd (so you don't get race conditions!) docs.microsoft.com/en-us/windows/win32/direct3dhlsl/interlockedadd

  • @antoinefortin1386
    @antoinefortin1386 2 роки тому

    Gold!

  • @stylie473joker5
    @stylie473joker5 8 місяців тому

    Works great but there is one issue Ambient occlusion from other objects is being seen through the object with TessellationSample material even when i enable After opaque (which usually fixes it) in the quality settings for ambient occlusion

  • @mrcresent
    @mrcresent Рік тому

    Drink every time he says 'tessellesation'.
    Also leave the man a like for this wonderful tutorial.

    • @NedMakesGames
      @NedMakesGames  Рік тому

      😆 I even knew this was the incorrect pronunciation! Thanks for watching!

  • @arthurgentz2
    @arthurgentz2 Рік тому +1

    Thank you for making this free. I had a quick look at the source code you provided, and as someone that knows nothing of shader scripting, it will take me a while to understand what's going on there. Anyway, i wanted to know how hard it would be to port this to Unity's shader graph? Are you aware of any nodes in the official Unity Shader nodes library that i could cobble together to achieve what you have done here? It's a lot to ask i know, so even just a point in the right direction would be of great help.

    • @stylie473joker5
      @stylie473joker5 8 місяців тому

      As far as i know Shader graph doesn't support Tessellation

  • @Yukiixs
    @Yukiixs 2 роки тому +1

    Hey, I learned a lot here, I would be very interested about how to use this technique with the grass compute shader of another video, so you would be able to select the grass density ( based on triangles sizes ), before we bake the mesh ... Tried to do that for long with other tutorials, but I can't figure out how to tessellate the mesh before computing the grass :(

    • @NedMakesGames
      @NedMakesGames  2 роки тому

      Hi, I'm glad to hear that!
      You're referring to my realtime compute shader grass, right? This is possible, but you'll basically have to reimplement the tessellation subdivision algorithm yourself. It's not super simple, but here are a few resources I found:
      graphics.stanford.edu/~mdfisher/subdivision.html
      en.wikipedia.org/wiki/Catmull%E2%80%93Clark_subdivision_surface
      en.wikipedia.org/wiki/Delaunay_triangulation
      I suppose it is possible to output the vertex positions from a domain function into a StructuredBuffer, which you could then read in your compute shader. You would have to get the shader to run before your compute shader and render to a texture you just discard. I think this would be pretty slow, but at least you wouldn't have to subdivide the triangles yourself.

  • @abdurahmanayesha608
    @abdurahmanayesha608 Рік тому +1

    Can this be extended to quad tessellation? If so how will the shader code change? And btw best video ever.

    • @NedMakesGames
      @NedMakesGames  Рік тому

      Hi! Thank you! Quad tessellation should work OK in theory, but you will have to change the algorithms for silhouette smoothing at the very least. You would need to expand the calculations to include four points.

  • @therandom446
    @therandom446 Рік тому +1

    Hey there! I don't know if you're still active on replies for this video, but I would still like to reach out and ask a question: Do you know of any plausible ways to retrieve the vector points generated on the GPU (with the tessellation) and give them to the CPU? I keep hearing about compute shaders, and how I could take the arrays of vertices and triangles and give those over, but I have no idea how to do so. The goal is to get the updated mesh and then apply it to a mesh-collider (since I didn't want to use raycasting for the movement in the demo i'm working on). Any help would be appreciated! Or links to where I can find the info.

    • @NedMakesGames
      @NedMakesGames  Рік тому +1

      Hi! I try to answer all comments but I've been extremely busy. I do apologize for the wait!
      You can't access a list of tessellated vertices, unfortunately. There may be some way to write to a buffer from the domain stage, but I would recommend just tessellating the mesh yourself in a compute shader. Then you can use that buffer to run a "normal" non-tellessating graphics shader, and send it back to the CPU.

  • @yeahnope620
    @yeahnope620 Рік тому +1

    The shader doesn't work, the very first line already gives the following error: unexpected TVAL_ID, expecting TOK_SHADER. Tested in URP 2022.2.10.

    • @NedMakesGames
      @NedMakesGames  Рік тому

      That's usually due to a typo in the ShaderLabs blocks. Does it give you a line?

  • @miguelsaldana5768
    @miguelsaldana5768 2 роки тому

    GOLD GOLD GOLD GOLD!

  • @benjohnson7610
    @benjohnson7610 Рік тому +1

    Seems like a really good tutorial, but unfortunately I just couldn't follow along. I tried copying the code in each section of the video but since I have no idea where some of these functions are hidden in unity I couldn't get the shader to compile. For whatever reason VertexPositionInputs is just completely unreachable to me. Really wish you could have included a complete copy of the file so I could have debugged my mistake and followed along.

    • @NedMakesGames
      @NedMakesGames  Рік тому

      Hey! Those functions are part of URP’s shader library. If you have URP installed, you should be able to inspect them using your script editor, though how is different depending on which one you’re using. In Unity’s preferences, there is an option to include code from packages in csproj files, which makes it appear in Visual Studio at least.

    • @benjohnson7610
      @benjohnson7610 Рік тому

      @@NedMakesGames Thanks for the tip. I tried including that option but it really didn't get me any further. Just found that I needed to include Core.hlsl but then I started getting redefinition errors. But thanks for the help anyway. I would suggest including a complete copy of the scripts you are walking through for future videos. The snippets are really nice for following a long but they cause a lot of issues if when viewers don't know the stuff that might seem obvious the the writer.

    • @NedMakesGames
      @NedMakesGames  Рік тому +1

      @@benjohnson7610 Hey, sorry for the confusion. Are you using the complete sample scripts, downloaded from the link in the video description? They're much too big to include in every shot in the video, but I will try to provide better context in the future!
      If you have URP installed, you shouldn't need to #include any other files than those already written in the sample scripts. What Unity version are you using?

  • @ThomasChen-ur2gt
    @ThomasChen-ur2gt 2 роки тому

    you are fucking awesome

    • @NedMakesGames
      @NedMakesGames  2 роки тому

      😄 Glad to help out, and thanks for watching!

  • @OdemGeek
    @OdemGeek 2 роки тому

    my comment is deleted, not the first time. Why? I spend a lot of time to write it in a foreign language)

    • @NedMakesGames
      @NedMakesGames  2 роки тому

      Hmm that's weird, I'm not sure why. I am not deleting them, and I even see them in my notifications. Sorry about that!
      But yes, you can use "SystemInfo.supportsT­esselationShaders" to check if your platform supports tessellation from C#! This is useful to switch between tessellated and non-tessellated shaders, if the need arises.

  • @darkdoom907
    @darkdoom907 2 роки тому

    Displacement map/Height map by shader graph Taaskuitttteeee senpaaaiiii;(

    • @NedMakesGames
      @NedMakesGames  2 роки тому +1

      Tessellation isn't possible in the URP shader graph, but you can still offset vertex positions by a height map.
      First sample it with a Sample Texture 2D LOD node and multiply the red component with a normal vector node in object space. Add that to the object space position and route it into the position field of the vertex master stack.
      If your mesh is dense enough with vertices, you should get a nice effect!

    • @darkdoom907
      @darkdoom907 2 роки тому

      @@NedMakesGames "First sample it with a Sample Texture 2D LOD node and multiply the red component ...." and then i didnt understood what u said ;)

    • @NedMakesGames
      @NedMakesGames  2 роки тому +1

      @@darkdoom907 😄 Maybe I'll just have to make a tutorial about it.

    • @darkdoom907
      @darkdoom907 2 роки тому

      @@NedMakesGames Thank you for the trouble, and sorry for the trouble caused;)

    • @NedMakesGames
      @NedMakesGames  2 роки тому +1

      @@darkdoom907 Oh no trouble! Thank you for watching!

  • @TijmenvandenHeuvel
    @TijmenvandenHeuvel 2 роки тому

    Yay no shader graph!

    • @NedMakesGames
      @NedMakesGames  2 роки тому

      😆 It is nice to code a little shader sometimes!

  • @MungeParty
    @MungeParty 2 роки тому

    3 minutes in and he's said tesselation 27 times, and correctly only twice. Oh boy..