Water Depth Shader - UE4 Materials 101 - Episode 24

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] in last week's video we started a new series on rendering water material and last week we were mostly focused on creating the ripples on the surface of the water this week we're gonna talk about depth opacity and depth color Before we jump into depth opacity and depth color what I wanted to do is show you a completed water shader that I've been working on so that you can see where we're headed you can see that we're using the ripples that we created from last week and we've also added our depth opacity and our depth color that we're gonna learn about this week and in addition to those two things we've also got reflection and refraction you can see the water under the surface here or the rocks under the surface are distorted or refracted by the ripples on the surface and if we look toward the horizon a bit you can see that the water has some really nice reflections so those are the things that we're gonna be talking about next week this week we're going to talk about a depth opacity and the depth color so let's jump right into it what we're gonna do is assign the water shader that we created last week to our surface which is called our water ripples demo and you can see that now all I have is the ripples I don't have any depth and I don't have any opacity I've got a little bit of reflection going on but no refraction so let's jump over to our shader this is the one that we created last week and we'll pick up right where we left off the first thing that we need to do is set some settings on the root node so right now if I select the root node here you can see that my shading that my material my blend mode is set to opaque and the first thing that I need to do is to set this to translucent and setting this to translucent is gonna allow me to create a material that has opacity that I can see through to show me what's on the other side of the surface now using a material with opacity I needed to create a little demo scene and so that's what I've done here because there are certain properties of my water shader that will not show up in my preview window here and so I put together just a very simple demo scene and I'll fly around that just really quick so you can see what it is I just copied some of these floor slabs I copied this small rock that comes with unreal and just kind of made up a little test scene that we can use for for showing off our water okay so we set our shader to be translucent and the next thing that we need to do is figure out the depth because there are two things that control the opacity of water one of them is the angle that you're looking at the surface and the other one is how deep the water is when when water gets deeper and deeper it gets more and more opaque so we need some way of measuring the depth of the water and there are two nodes that I want to show you that we can use to measure the depth the first one is called scene depth and the next one is called pixel depth and in order to explain what these two nodes do I want to switch over to a little bit of an illustration to help kind of walk you through visually what these nodes are doing okay so this illustration is our scene you can see that we've got water down here on the bottom and below the water we've got the rocks that are on the the bed underneath the water and here's a little icon a graphic that represents where our camera is and so we need to measure the distance from the camera into the scene and so that's what our first node is our scene depth so you can see that our scene depth measures the distance from where our camera is all the way through the water to the bottom this sends a ray that goes through the current transparent object and hits whatever is behind it so I get that the information that this node gives me is the distance from my camera to whatever is behind my water surface the other node that I have is called pixel depth and what this does is it gives me the distance from the camera to the water surface so here with the two of these things I have the distance from my camera to the water's surface and I also have the distance from my camera to whatever is behind it so if I subtract the pixel depth from the scene depth I get this new vector this blue one that is the distance from the water's surface to whatever is behind the water along the vector of the camera so that's gonna give me depth of the water now there are two ways of calculating depth and this is the first one so let's take a look let's jump back into unreal and take a look at the results that this is gonna give us what will build the shader and take a look at what we're gonna get this alright so I have my seen depth and my pixel depth and I just want to add a subtract node to the scene and I want to subtract my pixel depth from my scene depth and like I said before this is gonna give us that blue vector in the illustration that was the distance from the surface of the water to whatever is behind it now in order to control this a little bit I want to add a divide I'm gonna add I'm gonna divide by a constant and the value of this constant is going to be I'm just gonna give it a value of 100 for now and what this is is it's the depth of the water at what depth the water becomes completely opaque and I put a hundred and that's in centimeters so I'm gonna say my water goes from completely transparent to completely opaque in the range of 100 centimeters and then the other thing that I'm gonna do is apply a power node so that I can control the fall-off curve of the water and I'll show you what both of these to do in just a second so for my power node I'm gonna add a constant and then I'm gonna give that a value of 0.2 okay let's pass that in to base color just temporarily I'm gonna disconnect my normal here and pass this into base color just temporarily so that I can see what the results are going to be [Music] and I'm gonna save my shader and switch back to my scenes so that you can see what this depth is doing okay so you can see that I have something that is sort of an approximation of of depth right here on the surface I've got this little bit of blackness and then it falls off and goes white the deeper the water is and that's pretty cool now there is one thing that I need to do to adjust this so that we can see it a little bit better the first thing that I'm going to do is set my scene to unlit just so that we can only look at the color and then the next thing that I'm going to do is because the data that's passed into this base color pin is adjusted for gamma I'm gonna undo that adjustment and this this power node that I'm adding here is just purely for visualization just so that we can see linear data even though it's been adjusted for gamma so I'm gonna multiply or I'm gonna raise it to a power of two point two and that should give us a little bit more of a correct representation of the data that we're generating here so I'll switch over to my scene and now you can see that I've got this depth going on so here near the surface where the rock is poking out the rock is black and then as it gets deeper it gets more and more white so this is the data that I'm looking for I need to figure out or I need a value or to create a mask that is black on the surface so the opacity is near zero and then as I get deeper and deeper it gets more wide and more white there is a problem with the way that I'm calculating this though and I can you can see it right here as I rotate the camera around as I'm looking straight down I get this kind of depth value but then as I rotate my camera to more of a shallow viewing angle the depth information is changing and that's kind of weird so why is that well let's jump back to our slides and all I'll illustrate the the so here's our scene and the depth that we're calculating is from the surface of the water down to whatever's behind the water whatever's under the water but the problem is I'm rotating my camera to more of a shallow angle now and as I rotate it you can see that this depth vector is getting longer so the shallower my angle the more opaque my water is going to appear and that's not necessarily correct what we want to compute is a correct depth which is actually more like this we want to take the value where the camera vector hits the water and then compute the depth straight down from there to whatever is underneath the water so let's switch back to unreal again and I'm going to show you how to compute this actual depth value all right so we're gonna take our scene depth and our pixel depth and instead of subtracting them I'm going to divide them I'm gonna add a divided node and I'm gonna divide my scene depth by my pixel depth and now what I want to do is I want to bring in my world space position and I also want to bring in my camera position all right so I can use both of these but before I use them I need to adjust them based on the height of the water and so I'm going to create a third vector here I've got a position for my world my world position and my camera position but I need to create a third vector for the height of my water so I'm going to add a constant to vector that's just set to zero and then my height [Music] I'm gonna add as its own value so this is the height of my water this constant that I'm creating here and I happen to know that if I switch back to my scene here and select my water I can see that it's located at 70 above the origin of the world and so I'm gonna put a value of 70 in here and I'm gonna take this vector and I'm going to subtract it from both my camera position and my absolute world position all right so now I've transformed my absolute world position in my camera position into the space of the water height and so now I can cast a ray from the absolute world position to the camera position I'll do that by using a subtract and now I'm going to multiply by this value up here that I calculated the scene depth okay and then finally I'm gonna add these two values together and I only actually need the Z component because it's the height that I'm looking for and so I'm gonna move this over and I'm gonna add a component mask and I only want the Z so I'm going to turn off the X and the y just leave the Z and then the last thing that I need to do is invert it so I'm gonna do a 1 minus and then this value I'm going to pass into here like this ok so now I've created an accurate depth value now there is a drawback to using this accurate depth value if you have a water plane that's not flat like if you're doing a river that's running down a hill you wouldn't be able to get this height value very well and so you would want to use this approximation where you just subtract the pixel depth depth from the scene depth in that case or if you have tons of different water planes and you don't want to worry about inputting the height of each one you could use this approximation instead but in cases where you can compute this height and apply it it's much better to use this more accurate version alright let's save this and jump back over and see what it looks like in our scene alright so my scene turned out to be solid white and that's because I made one mistake in the shader we need to switch back here and instead of adding the result of this subtract we need to add the result of this subtract and that should give us what we're looking for alright so now you can see that as I'm moving around the scene my depth is staying constant and that's exactly what I'm looking for okay now there are two more contributing factors to opacity there's the angle that you're looking at it and then there's also one more little thing that I want to do on the very edges so let's let's talk about the angle to measure the angle between the surface and my viewing angle we're gonna use a node called Fornell so I'm gonna skip over here and come in here and add Fornell node and internally what this node does is it does a dot product between the eye vector and the surface normal and it will return a value of 1 if those two vectors are parallel but if they're perpendicular it will return a value of zero there's also a an exponent value here and I need to set this value to something that's a little bit more appropriate for water so in this case I'm going to set it to 3 instead of 5 and what I'm gonna do is come down here to where I've got this power coming out and I'm going to add in my friend Nell and now let's see what I get with my mask oh actually before I do that I need to saturate the result to make sure that I don't go over a value of one so this will clamp it between zero and one okay so now you can see I have my depth but when I'm looking at it at an angle like this the the depth is opaque and what I'm looking down into the water like this there's more transparent but as my angle changes I'm able to get some some opacity that's nice now there is one thing that I forgot to do and that is I forgot to use my normal because my normal that I have here actually should be the normal that I'm generating with my ripples now there is one nice trick that you can do in unreal whatever you pass it because mmm let me back up a little bit whatever I use in this normal needs to be in world space and these ripples that we computed last week in that tutorial these are actually in tangent space but what happens is whatever I pass into the normal socket on the route here I can access that this normal here in but it will be computed or it'll be converted to world space so I'm gonna plug this normal in and now I'm going to bring in a new node that's called pixel normal WS and the WS stands for world space so if I pass that into my normal socket my friend L term will now be using the normal that I computed with all of this but it's been transformed into world space which is what I need to do my fernell computation so let's take a look and see what that gives us as a result and once again it's giving us not the result that I was expecting and that is because I forgot a setting so let's switch back to the shader and if I come over here to the root node and select it I need to set my lighting mode see how it's set to volumetric non-directional I actually need to set my lighting mode to surface translucency volume and when I had it to a volumetric non-directional I don't know if you noticed but this normal socket is grayed out and what that means is that it's not accepting input this particular lighting mode doesn't use normal input and so I need to change my lighting mode to surface translucency volume which now allows me to input it normal okay so let's save this and switch back to the scene and here you go so we've got the surface ripples happening and as I look down into it we got some nice depth but as I change my view angle we get some some more opaque water and you also can see that the Frenette amiss doing some really nice effects with the surface ripples okay so we're almost ready to use this opacity but there are there is one more thing that I want to do one more trick up my sleeve so let's switch back to the shader again and this time we're gonna add another node called depth fade and what the depth fade node is gonna allow us to do is to so if we switch back to the scene here you can see that right around the edges there's this really hard line between the rocks and the water and what I want to do is kind of fade this out so that right at the edges of the water there's some night there's a nice transition instead of a hard line so I'm gonna add in this depth fade node and so just right here after my saturate I'm gonna multiply this value that we've computed by the depth fade and if I come here to the depth fade mode you can see that I have a couple of parameters the opacity and the fade default and in my case I'm gonna set now this is a value in centimeters and I'm gonna set my centimeters to 30 so that it's just baby hot right at the edge it will pass that in again so now you can see all the places where the rocks are intersecting the water plane I've got this darker opacity value which means the water is gonna be more transparent in those areas okay so we've been passing our opacity value into the color and that's just so that we could see what it looked like but now we actually need now that we've computed this value correctly we actually need to pass it in to the opacity so I can take the result of this multiply here and pass it into my opacity socket and I can get rid of this power node here that's going into my base color so let's save that and take a look at what it looks like in our scene when we're actually using the opacity value that we computed as opacity for the water alright cool so you can see that my water is the default dark black color in places where it's opaque and where it's transparent you can see threw it down into the depths and that's the result that we're looking for okay the last thing that we need to do is get some color for our water and so what we can do now is what we observed in the reference footage that we watched is that the water changes color as it gets deeper and we have our depth value right here so all we need to do is add a linear interpolation node and we can use one color for the water where it's shallow and then the other color for the where it's deep and I've worked on this a little bit and I found some colors that I really like this one is kind of a light blue color and then this one is a dark blue color and so I'm gonna pass this one into the B socket and this one into the a socket and then instead of leaving this empty I'm gonna wire the result of this Lert into my base color alright so you can see that I've got this nice light blue color where the water is shallow and where it's deep it turns kind of that darker blue color now i can turn my lighting back on because I'm looking at it unlit and you can see I'm getting a little bit more realistic looking results alright so just to reiterate here we've computed depth using our world space position our camera position our scene depth and our pixel depth and then we're dividing that depth by our maximum depth which right now is a hundred but if you wanted your Val your water to be clearer further down you could increase this depth value to something over a hundred and then we're adjusting the power or the fall-off curve on the water and we're using a value of point two but you could use something else if you wanted to and then in order to make our water more opaque when you're looking at it at glancing angles we're adding a Fornell term here and then finally to make our water transparent on the edges we're adding a little bit of depth fade and then that is our opacity and then we're also using our depth to determine a light blue color for shallow water and a darker blue color for for deep water so that's the tutorial for today remember next week we're going to talk about reflections and refractions and end up with the water that I showed you at the very beginning so be sure to subscribe to the channel and hit the notification bells so that you'll know when a new tutorial comes out I try to publish these every I hope you enjoy it and I'll see you in the next video [Music]
Info
Channel: Ben Cloward
Views: 19,508
Rating: undefined out of 5
Keywords: UE4, Unreal, Unreal Engine, shader, material, material editor, game development, real-time, tutorial, training, Unity, graphics, 3d, GPU, tech art, computer graphics, fundamentals, basics, beginning, learning, water, ripples, depth, opacity, PixelDepth, SceneDepth, PixelNormalWS, Fresnel
Id: TObymSnTwV0
Channel Id: undefined
Length: 25min 3sec (1503 seconds)
Published: Thu Apr 30 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.