Saturday 26 May 2018

Fancy Shaders - Part 3: Deformable Surface with Tessellation

Snow deformation in "Assassin's Creed III" by Ubisoft.
Image is taken from lanoc.org

Hey! This is another post in Fancy Shaders series and I want to touch another cool topic - surface deformation. It's not something that is being used in every game these days but is getting more and more popular. So what's special about it?

Well, there may be certain situations when we want to change the surface of the ground and make it as realistic as possible. Just think about footsteps on snow or sand! Many games had been using different tricks for achieving that effect, but it looked fake most of the time. However, since DirectX 11 has introduced tessellation, developers started using other methods for solving that problem. Today I'm going to shortly talk about a common and quite simple way to deform surfaces in real-time using DX11 and Unity. Of course, I'm not going to talk particularly about tessellation, because it's a big topic, but do not worry! Unity can do a lot of things for you! 

In general, with tessellation enabled in your pipeline, we can increase the number of vertices and polygons of a mesh by subdividing its parts. We need to do that if we want to move the triangles and reshape the mesh in order to fit the "collider" (foot, for instance). Fortunately, it's easy to enable tessellation with Unity's Surface Shader. For example, below is the implementation of distance tessellation from Unity's documentation:


Ok, we prepared our surface for deformation, but what's next? Have you ever tried to work with heightmaps? Actually, we can use the same method for making hollows! We get information from a heightmap texture and then subtract our normal*displacement from the vertex instead of adding. Alright, that was not difficult, but how to generate that texture in real-time? We can do that with one extra shader and a script. In a shader we are going to simulate a brush, like in terrain editors:


And then in a script, we do a simple raycast to the ground from our "object-collider":

It's not really optimized, as performance will drop if we do raycasts from a huge number of objects, but even like that it looks pretty neat in Unity!




So you can actually use that idea for simulating sand, mud or other similar surfaces... What I showed you is a basic setup and there may be a lot of improvements. Personally, I can  think of these games with something similar: "Batman: Arkham Origins" by WB Games MontrĂ©al, "Rise of the Tomb Raider" by Crystal Dynamics and Eidos MontrĂ©al, "Assassin's Creed III" by Ubisoft and one recent title - "God of War" (2018) by Santa Monica Studio. I highly recommend reading their papers if you want to improve your surface deformation, because they described their own ways and optimization guidelines for this feature.

Links:

Other useful resources:
1) "Deferred Snow Deformation in Rise of the Tomb Raider" by A.K. Michels and P.Sikachev, from GPU Pro 7

No comments:

Post a Comment