Rain Ripples Shader - UE4 Materials 101 - Episode 16

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] in today's episode we're gonna create a rippling water effect for the last couple of weeks we've been creating shaders that imitate the effects of rain and so today we're gonna build on that a little bit more last week we created a shader that made rain drips running down the sides of an object and the week before that we created raindrops well today we're gonna create the results of rain falling into a puddle you can see here in this reference video that I shot that when rain falls into puddles it creates these really nice concentric ring ripples and so that's the effect that we're gonna be going for in today's tutorial all right so we're gonna jump into unreal and the first thing that we need to do is create a single ring mask that's animated we want the ring to start really small in the center and then grow and then fade out and so we're gonna start out with texture that looks like this and this is just a simple radial gradient texture I created this in Photoshop by turning on the radial gradient and then just dragging my gradient from the center to the edge pretty simple to make this kind of a texture well this isn't exactly what I'm going for you can see if I just plug my red channel right into base color I'll just get a radial gradient over here if I turn on my live preview but what I want to do is animate this effect so let's go ahead and add a time node because time is the basis for all animation and in this case I want the fraction of time so I'm gonna add a frac node what frac does is no matter what the integer value of this is it throws it away and just returns the decimal portion or just the numbers that are on the right side of the decimal not the left side so if I wire time into frac I'll get this repeating number that goes between 0 and 1 and then jumps back to 0 again and that's the effect that I'm going for because I'm gonna do this ripple as a loop so it's gonna start out small grow and then loop back again the next thing that I'm going to do is subtract 1 so I need to create a constant node and I'll give it a value of one and now I'm gonna add that to my ripple so if I create an ADD node and then I'll add my radio gradient texture to that let's see what that gives us okay that's not exactly what we're looking for but we are making some good progress you can see that we've got this nice radial gradient that's growing it starts out small and grows large and then jumps back to small again so this is the very beginning of our animated ripple effect the next thing that we can do is increase the contrast a little bit so I'm gonna multiply my value by some really big number so let's add another constant and I'm gonna give it a value of 20 so this value is controlling the contrast of my ripple or the sharpness of the edges of the ripple and now I'm gonna clamp that between zero and five now if I want to create a ripple effect what I really need to use is a sine wave and so I'm gonna add a sine and let's plug this into my sine wave and take a look at what we get because what a sine wave will do is as the value goes between negative 1 & 1 it will create a loop and so what we want instead of this gradient here we want a repeating pattern from 0 to 1 0 to 1 0 to 1 so that's what our sine wave is gonna give us so let's see what happens when we plug that in okay now we've got some pretty decent looking ripples and that's what our sine wave is doing as our value goes between 0 & 5 our ripples are going up and down up and down up and down now I do want to point out one thing that's really interesting and unique to Unreal editor and that is that the sine function is not exactly the sine function you might see in other contexts because it has this period value generally if you if you do a sine function most sine functions will default to a period value of 2 pi and so if I want this sine function to behave like a sine function in standard math I need to give it a period value of six point two eight three one eight five and no I don't have that memorized I'm just reading it all right so now now that I have a standard period value you could see that I'm getting a single ripple now if I want more than one ripple like I had before I can multiply this result here by a value of Pi so I'm gonna move some nodes over here just so I have some room and then I'm gonna plug in PI and this is really interesting because so I can just pick pie and lay that down I'll connect to my clamp node to the left-side of pie and the result output and that will multiply this bit by pie now you can see that I've got these really nice triple ripples here coming out from the center and that's exactly what I'm looking for so I've got a really good start now the next thing that I need to do is figure out how to get these ripples to fade out at the edges right now when they get to the end of the cycle and they're as big as they can be they just blink out and immediately jump back to to being small again but what I really want to do is change the ripples so that as they get bigger they fade out and what I can do is I can take my time value so as it gets larger what I'm gonna do is add a 1 minus node so I'm gonna take this time value and as it gets closer to 1 I'm gonna feed it into here so as it gets closer to 1 the value is gonna get lower and lower so I'm changing my range as it goes from 0 to 1 to actually go from 1 to 0 so that means the further along it gets toward the edge the darker this value is going to be and then I can just take my result and multiply it by the 1 minus value and that will give me a nice mask that will darken my rings the closer they get to the edge now you can see as the rings get closer to the edge they're also fading out okay the next thing that we need to do now that we have a really nice mask for the Rings is to convert this ring mask into some normals and so in order to do that I'm gonna change the texture here I'm gonna pick instead of raindrop gradient I'm gonna pick this texture that's called raindrop and let's take a look at what this texture looks like so here's our raindrop texture and it has these really funky looking colors and so I'm going to break this down one channel at a time just so you can see exactly what's happening here in the green and the blue channels I have the normals of a cone so I've taken a cone looking at it from the top down and generated a normal map from that so you can see here's my green Channel and here's my blue Channel and so these are the normals that I'm gonna use for the ripple and if I show the red channel you can see that this is the radial gradient that I was using before so let's jump back to our shader and you can see here I'm getting the exact same result with this texture that I was with a regular radial gradient texture and that's because it has the exact same thing in the red channel but in the green and the blue Channel I have the X and the y component of my normal and that's what I need to be able to create this effect so I need to take the green in the blue Channel and make a normal out of it and this is kind of similar to what I did with the drips and the drops so I'm going to take my append vector node and I'm gonna feed my green and my blue into so now that I have now I have a Veck to value here with the X and the y of the normal and now just like I did before I'm going to multiply by 2 and subtract 1 and the reason that I'm doing this is I want to expand my normal value from a range of 0 to 1 to a range of negative 1 to 1 so that I can have a vector instead of the color data that's stored in the texture here so I'm going to multiply by 2 and subtract 1 and so now I have the first two components of the normal data that I'm looking for so if I want to make it normal now I need to append one more value to that so that it becomes afloat 3 so I'm going to append a constant value of 1 and if I were being really accurate I could derive the Z value of my normal and use that here but instead of doing that I'm just gonna use a value of 1 and this is a performance optimization so this is not strictly speaking mathematically correct but just using a value of 1 as the Z component for the normal makes it run a bit faster okay so if I value if I wire this directly into my normal socket now you can see that there's this cone-shaped normal on there and what I want to do is animate this normal based on this mask that I have and so before I append this value here I'm just gonna multiply my X and my Y values by this mask that I've created so I'll add another multiply and bring in my mask and then feed the result of that into my normal so now let's take a look and see what we get I'm gonna break my base color here so you can just see what the normal is doing and if you take a look really closely you can see that I've got this really nice ripple shape and that is exactly the effect that I'm going for so pretty cool alright the next thing that I need to do is instead of just having one ripple I want to have a whole bunch of ripples and so I need to take this texture that I've created and duplicate this shape a whole bunch of times or I need to create a texture that has a whole bunch of these on it not just a single ripple and I actually happen to have one of those already so I'm just gonna pull this down and select my reign ripples texture so you can see in this texture I have a whole bunch of these ripple shapes so each of these is exactly the same as this so it's it's making a bunch of them instead of just one so now you can see I need to zoom in a little bit closer here but now you can see I have a whole bunch of ripples instead of just one but there is a problem and that is you can see that all of these ripples are happening at the same time and so we need a way to offset them so they each have their own time to happen and the way that we're gonna do that is with a temporal offset map similar to what we did before with our rain drips and our raindrops so let's take a look at this texture again that we're using and what I've done is I'm gonna show the Alpha Channel here so what I've done in the Alpha Channel is make each of these circles have a different value of gray and this is our temporal offset map so I can use this channel the Alpha Channel and add it to time so that each of the ripples happens at a different time so I'm gonna take the Alpha Channel and wire that into an ADD node and I'm going to add it to our time value and now we get the ripples happening at a different time and just really quickly I'm going to add a constant here this is just to make it a little bit easier to see what's happening and I'm gonna wire this into the roughness so that we can get a nice nice looking result there we go so you can see that I've got these really nice-looking ripples they start out really small they grow big and then they fade out at the end so this is cool this is the effect that I was going for and maybe there's just one or two other little things that I want to do these ripples might be a little bit too strong so if I come in here and add a multiply node I'm just gonna multiply this by a constant value of something like zero point three five just to tone it down just a little bit and that will be the effect that I'm looking for so there you go we have some really nice ripples now we could just leave it here but there are some more things that I want to do if you take a look back here at this reference video of the puddle you can see that I have lots of ripples and the kind of chaotic happening at different times and especially notice that the ripples are overlapping each other if we come back to look at the effect that we created because of the way this texture is set up none of the ripples ever overlap each other they expand but they don't ever run into a ripple next to them so in order to be able to do that we need to take this effect all of these nodes in this shader that we've created and do them multiple times and then add them together so that's the next thing that we're going to do all right in order to make all of this happen multiple times I need to take all these nodes and turn them into a function node and so I've gone ahead and done that ahead of time and I'm gonna drag this new shader over here and show you how this works so this shader is exactly the same as as this shader it's just turned into a function you can see here that it's got this like light blue icon with the F which means it's a function so there are just a couple of things that I changed first of all instead of the root node here I added a function output node and that's important because you want to be able to output the data of your function secondly I've created these input nodes so I'm inputting my UV coordinates I'm inputting my time and I'm inputting a wait now this wait is just a little bit different than what I was doing before here you can see I have my one minus which I was using to fade out the rings at the end but instead of using this 1 minus node I've replaced it with this set of nodes here I'm bringing in my wait multiplying by 0.8 adding point two and then subtracting my time fraction saturating that and then using that so this is just a little bit more complicated way of doing my 1 minus fade out and it allows me to combine the fade out with a little bit of a wait and I'll show you the purpose of the wait in just a minute so I've created this function and now what I need to do is make a new shader where I call this function multiple times and just like a good cooking show I've already done that so here is the shader that I've created where I'm calling my weather ripple function four times you can see that I have the weather ripple function here and there are four copies of it and they're all being combined together and then I'm outputting my result this may look kind of complex this particular function but I'm gonna walk us through it basically what this is doing is it's calling the function four times using different time values different UV values and different weight values and our goal is to create these ripples where each copy is a different size loops at a different speed and is placed in a different location in space and the purpose of that is to make it so that the ripples don't Teil and don't loop so first we need to create four different values for time so I'm taking my time node and I'm plugging it in to each of the four slots of a vector and then I multiply it by a couple of different values and I add a couple of different values to it then I have an overall speed value which is one point six and then I do a frac and I break it up into its individual RGB and a components so these four values here are different times that I can use in my different ripples the next thing that I do is I'm doing the same thing for my UV coordinates so I have UV is coming in and then I'm adding different values to them and also multiply them multiplying them by different things so that I can get ripples that are different sizes and scales and finally I have my weights and I'm multiplying my weights by 0.25 0.5 and 0.75 and this is gonna break up the weights so that I have kind of like four different sets of ripples that are dialed in depending on how intense it's raining so if it's raining zero I'll just get a little bit of ripple but if it's raining all the way up to one I'll get the full amount of ripples so I have four different values for time for different values for my UV coordinates and also for different values for my weights and I passed those values into my four ripple functions then finally I combined so the result of the ripple functions are ripple normals so finally at the end here I combined the four normals together and here I have another function that I've created and I'm gonna show you what that one looks like so here I have my four normals coming in and I take the X and the y of each of those and multiply it by my weights so I have my RGB and a values for the weights multiplying by the X&Y of the normal vectors then I'm adding the X and the y components together and down here I'm taking the Z components of the normal I'm combining that I'm into a single vector and blending them between one and that based on my weight values then I'm taking the RGB and a and multiplying them together and then I get my final Z so this is my X and my Y and my Z and I append them together normalize them and pass them out so that's how I'm combining my four different normal values together and then the result of that gets passed out so all my four different animated ripples are combined together here at the end and the last thing that we need to do is create one final shader that uses all of them so I'm gonna go in here to my materials we're gonna create a new material and I'm just gonna call this ripples test and we'll open it up add our ripples function to it and see what it looks like so here is our ripples function and it's kind of surprising like all of the work that we've done so far is encapsulated in this one little node and that can be deceiving sometimes so you kinda have to be careful with that I'm gonna I'm gonna put our new shader here in this same window just so that we can look at it all together we have to be a little bit careful with that because this node is small and it looks like it's not doing very much but really it has all of this in it and then all of that is repeated four times here and then combined together and all of this is all encapsulated in this one single node so we need to be careful how we use this I'm gonna wire it into the normal and I'm gonna set our roughness value to a value of zero just so we can visualize this let's set this to be a box and we need to pass some texture coordinates into it and we need to give it an intensity of one and now we have the final result of our ripples so let's take a little bit closer look at this and I'll show you what's going on so you can see we have ripples here that are overlapping each other and happening at different times and because we have four copies of the ripples that are all happening at the same time they're able to loop at different times and tile at different rates and so we never end up with a pattern that repeats itself so that's pretty cool all right so next week we're gonna take a look at how to take this function and combine it with some other things to turn it into a puddle and the puddle is gonna be able to grow depending on how long it's been raining so be sure to subscribe to the channel hit the notification bell to know when the next video comes out and I'll see you in the next video [Music]
Info
Channel: Ben Cloward
Views: 20,310
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, rain, water, ripples, puddle
Id: ABWzKYc6UQ0
Channel Id: undefined
Length: 26min 27sec (1587 seconds)
Published: Thu Mar 05 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.