Hi JetGuys, have you ever wondered how to generate a
depth effect on a shader? In this chapter we are going to
answer to this question and for that we are going to recreate the Cracked
Ice Effect in Unity, using Shader Graph. Stay until the end and find out
how to generate this shader very technical and quite useful
for christmas seasons or even for a sci-fi stage. Theory To generate this shader we must take
into consideration certain factors: the first is that we will sample
various textures in 1 pass to generate the effect of depth. Working with multiple samples will make our shader very heavy for the GPU, for that reason we are going to optimise operations to work on mobile devices. Once we have all of this we are going to divide each texture
by the amount of samples since in this way we will obtain
a gradient depth effect. Getting started In my project I have created a
new folder called Cracked Ice, within it we can find several folders that contain the files
that we will use in this tutorial. Remember that you can find all those files in our patreon. also if you want to go deeper you'll also find
documentation in both English and Spanish about our tutorials, link in the description. The first thing we're going to do is
to create an Unlit Graph shader lets call it cracked ice Then we create a material and call it the same. We assign the shader to the material from the material inspector. To understand what we will do, we're going to start by working with a Quad, for that reason we go to the hierarchy
and create a Quad. we call it Ice. This Quad is going to represent the ice in our scene, for that reason we have to rotate it 90 degrees until
the main face points upwards. We assign the material to the Quad
and then open our shader. We start by setting the lighting, for this we bring a Custom Function node. I have previously created a hlsl file called IceSpecular that itself contains
only lighting direction and its specularity. We pass this file as "Source" and as "Name" we use IceSpecular as well. In order to our node compile
we must add the inputs and outputs, and also make its precision equal to half. So, we start with the inputs. We add a 3-dimensional vector and we call it Specular. We add a 1-dimensional vector and we call it Smoothness. We add a 3-dimensional vector and we call it Color. We add a 3-dimensional vector and we call it WorldNormal. We add a 3-dimensional vector and we call it WorldView. Finally as output we add a 3-dimensional vector and we call it Out. Done, our node is
compiling perfectly. We group this node and we call it Light Specular. What we are going to do next is to go to the blackboard and we are
going to create some properties We add a 1-dimensional vector, we call it _Specular and it has to be a Slider between
0 and 1 with 0.5 by default. We create a new 1-dimensional vector, we call it _Smoothness and it has to be a Slider between
0 and 1 with 0.5 by default. Finally we add a Color, we call it _SpecularColor and it has to be white by default. We drag the properties to the node area, we connect _Specular with the Specular input, _Smoothness with Smoothness and _SpecularColor with Color. For the Input WorldNormal we bring the Vector Normal Node. Then we bring the node "View Direction" and we connect it with WorldView. We must make sure that both nodes
are configured in World Space. Ready, we now have configured the
Specularity for our ice. To understand what we are doing, we are going to connect the specularity
with the Unlit Master Color, we save and return to Unity. As we can see, the specularity it's working perfectly, now we are going to continue with
the depth effect. Making the depth samples For this effect we are going to use a Custom Function node too, however before continuing
with the HLSL function, we must go to our blackboard to add some properties. We add a color property, we call it _Color and
it has to be white by default. We use this property to
change the color of the ice texture. We add a Texture2D property, we call it _MainTex and we pass it the texture of ice that
we have in our project. We add a 1-dimensional vector, we call it _Samples and it has to be of integer
type with 8 Samples by default. We add a 1-dimensional vector, we call it _Offset and it has to be a Slider between
-0.01 and 0 with 0 by default. We add a new 1-dimensional vector, we call it _Lerp and it has to be a Slider between
0 and 1 with 0.5 by default Finally we add a 1-dimensional vector, we call it _LOD and it has to be of type integer with 0 by default. We drag the properties to the node area. I am going to explain these properties
as I implement them. I have previously created a hlsl script called IceDepth as we can see we have
an input for Texture2D, an Input for our UV coordinates and an Input SamplerState. We also have an input called Samples which corresponds to the Samples that
we are going to create for the depth effect, an offset to differentiate the
position between each sample, a vector called WPOS that corresponds to the position of the vertices in world space, a vector called Lerp that allows to do lerp between texture and depth effect, and an integer input called LOD which allows us to adjust the resolution of the depth effect so
that it works on mobile divices. So first we initialize the
vectors that we're going to use, then we generate the function
that allows us to differentiate each sample in the effect and add an offset to the UV coordinates of each one, multiplying the position of the camera minus the position of the vertices in world space. Then we divide the samples that
we have saved in the col vector, by the amount of samples in our function. We finally make a
lerp between the first texture and the samples we have generated. (back to Unity) Then, within the
configuration of our node, we must pass IceDepth as Source and as name we use IceDepth as well. As we already know, In order to our node compile we must add the inputs and outputs, and make the precision equal to Half. We start by adding a
Texture2D type property and we call it MainTex. Then we add a 2-dimensional vector and we call it UV. We add a SamplerState and we call it SS. We add a 1-dimensional vector and we call it Samples. We add a 1-dimensional vector and we call it Offset. We add a 3-dimensional vector and we call it WPOS. We add a 1-dimensional vector and we call it Lerp, and finally we add a 1-dimensional vector and we call it LOD. As output we simply add
a 4-dimensional vector and we call it Out. So we connect the main
texture with the MainTex input. For UVs, we bring in the UV node and connect it. We leave the input Sampler State with its default value. We connect _Samples with Samples, _Offset with Offset and _Lerp with Lerp. In the case of WPOS, we bring the node position and connect it. Finally we connect _LOD with LOD. The _LOD property will allow us to adjust the resolution of the texture so that this function can
run on mobile devices. Before continuing we must go to our blackboard, to create a 1-dimensional vector, we call it _Saturation and it has to be a slider between
1 and 2 with 1 by default. We drag the property to the node area and we multiply our custom
function by this property. Now we can adjust the Color Saturation in it. Then we multiply again but this time by the _Color so we can change the
color dynamically. Now we simply add both operations and we connect with the color of the Unlit Master. We save and return to Unity. As we can see, both the texture and the _Offset
They are working perfectly. If we increase the offset we can
see the depth effect. To have a more finished effect we can increase the number of Samples, however, if we do this the
GPU will consume more resources. Therefore, it is advisable to increase the _LOD to decrease the resolution in the effect. Our effect is done I invite you to modify the parameters
to get different results. If you liked this tutorial, support us on patreon since in that way we can continue creating video
tutorials for the community. Thank you very much for joining us, Jettelly wishes you success in
your professional career.