Half-Life: Alyx - Liquid shader in Unity

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
Lately, our twitter feed, was literally full of bottles containing liquid directly from the last chapter of Half-Life (Alyx). A lot of good talented creators made their version of this cool effect. Today we'll create our version of it on Unity. The effect consists in showing a mesh, inside the bottle, and make it look like a liquid. To easily care about the lighting, we used a surface shader instead of a fragment. Besides a good aesthetic, to make a mesh looking like a liquid we have to cut the surface at a certain level. So we started from that point. In our liquid shader, we exposed a position and a normal vector that represent a plane. That plane is the max level of the liquid. Using the dot product between the mesh position minus the plane position, and the normal of the plane, we were able to determine which part of the mesh we need to show. We cut out the other part discarding the color if the dot product is higher than zero. Because we sliced out the mesh we had divided the front and the back faces. For the front faces, everything was quite simple. We used color, a texture, a normal map, the glossiness, and the metallic value. For the back faces, besides the color, the metallic, and the glossiness, we needed to transform the normal vector to match the normal of the plane used before. We needed it to pretend that the upper border of the mesh was closed and cover the hole. To do that, since we used a surface shader, we had to create a matrix that converts the world coordinates to the tangent space. Also, we used a normal map with the world UV to enhance the refraction while moving. Using a script, we connected the position and the normal of the plane in the shader with a real quad. To pretend to keep the liquid volume inside the bottle, we adjust the position of the quad depending on the bottle rotation. We exposed a property called "bottleHeight". We consider the top of the bottle starting from the base and going up at the bottle "bottleHeight" distance. We moved the quad on this line, and we did a proportion to figure out the distance that it has to keep from the base. If the top of the bottle has a lower Y value of the base, we switch them. To approximate the level of the liquid in a non-regular shape we simply used a lower value for the "bottleHeight" property. Let's talk about the movement, while the player moves the bottle we calculate the velocity and keep track of that. We rotate the quad to facing that direction so the liquid seems to be affected by physics. When the magnitude of the velocity is zero, so nobody is moving the bottle, we use the accumulated velocity to simulate the inertia. With the ping-pong function, we go back and forth from the facing direction to the opposite one. Carrying that value to zero in time, allows us to simulate the end of the inertia. We did the same operations even for the angular velocity while the player rotates the bottle. Back in the shader, we interacted with the stencil buffer to cover the backfaces and improve the top surface aesthetic using also a custom shader on the quad. The stencil buffer, allows us to prepare a mask of bit and render an object only if the buffer has the same values. So we need a shader that writes on the stencil buffer and another one that can read from that. In the liquid shader, we divide the two cases to avoid covering also the front faces. If you want to go deeper in the stencil buffer check the description below and you will find Harry's and Ronja's articles about that. In both of the shaders, we provide a property that represents if the inertia is still present. We used that property in the liquid to animate our threshold in the "checkVisibility" function and ruffle the top edges. In the top surface shader, instead, we used that property to enhance the normal map value and faking a ripple. As an additional and optional experiment, we wanted to allow the liquid material to be transparent. In this case, we drew both faces: back and front, so we decided to use a grab pass. A grab pass is a particular pass that grabs the content of the scene and draws it into a texture. This is can be expansive in terms of resources but it's commonly used when you want to distort an image. We used that in a previous video where we recreated the heat distortion. After sampling the texture, we used the alpha property of the color as a weight for the lerp between the color or the background texture. We downloaded a model of a bottle from Sketchfab and merge the inner meshes to use a single material. This is the final result! If you follow us, you know that in the last weeks, we are working on a framework to create web augmented reality experiences from Unity. So, as the last test, we wanted to try this in our "work in progress" framework. Don't forget to subscribe, smash the like button and follow us on the other socials. Also, If you are interested you are welcome to our discord server. See you next time. Cheers
Info
Channel: TNTC
Views: 26,420
Rating: undefined out of 5
Keywords: gamedev, unity, unity3d, game development, gameart, development, indie, TNTC, tntc, unity3d tutorial, game dev, indie gamedev, Alyx, half life alyx, half life, liquid shader, liquid in bottle, half life liquid effect, half life bottle effect, web ar
Id: dFv8lM-kS4E
Channel Id: undefined
Length: 8min 5sec (485 seconds)
Published: Fri Jun 19 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.