Making a rainy window in Unity - Part 1

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments

This is sick, thank you so much I'll be using this.

👍︎︎ 3 👤︎︎ u/snalakai17 📅︎︎ Mar 24 2019 🗫︎ replies

Nice stuff, what i liked the most is that you dont over-explain things; the pace is perfect to follow for people with basic shader understanding in order to learn something without being overwhelmed.

👍︎︎ 3 👤︎︎ u/jdooowke 📅︎︎ Mar 25 2019 🗫︎ replies

Shaders have always felt like magic to me, but you've offered some great explanations. Every time you ran into a tricky problem such as with the droplet getting cutoff at the edge, or the float number precision, I was thinking "hmm how would I solve this". Then a few seconds later you'd make a simple change and boom problem solved. Immediately I understood the solution and I felt that I gained a little kernel of knowledge.

Thank you for creating this, I look forward to part 2!

👍︎︎ 2 👤︎︎ u/speedtouch 📅︎︎ Mar 25 2019 🗫︎ replies

Thank you so much for this!

👍︎︎ 1 👤︎︎ u/gamedaverookie 📅︎︎ Mar 25 2019 🗫︎ replies

Look really nice, good job!

👍︎︎ 1 👤︎︎ u/Orzo- 📅︎︎ Mar 25 2019 🗫︎ replies

Excelent

👍︎︎ 1 👤︎︎ u/diegochak 📅︎︎ Mar 25 2019 🗫︎ replies

Thank you for posting this! I just spent the last couple hours watching the tutorials on your channel, and I feel like I've already got a bunch of new shader tricks up my sleeve.

You explain things at a really good pace. Not too fast or slow, and easy to follow and understand.

👍︎︎ 1 👤︎︎ u/mfirmin8 📅︎︎ Mar 25 2019 🗫︎ replies
Captions
hey a little while ago I made an effect that shows a rainy window and I made it in shader toy though and I figured that it could be pretty cool to use that in a videogame so I decided to revisit that effect make it a little bit cooler and make it in unity so that you could potentially use it in a video game or any kind of interactive installation that you might be thinking of so what we'll be making in this project is this shader over here so here we have a plane with the shader on it and yeah it's transparent you can look through it but it's it makes the background kind of foggy and you see like a bunch of these drops here so pretty cool so let's let's try to make this from scratch I'm gonna do is I'm going to make a new material down here so I'm gonna go create shader and then I'm gonna make an unlit shader for this one and let's call it window and let's have a look at that shader so I just double-click on it and now I also have to apply that shader over here so let's go click over here and then we're gonna go unlit and then the new one that I just created window so that just creates a standard unlit shader that has only one texture on it so so let's get to work with this so let's go over here and let's go into D into the fragment shader which is that last part over here now let's just get rid of this and let's just make a black a black screen for now so I'm gonna go here equals zero and zero and so now I have a black screen and now I'm going to make a grid because there are going to be a bunch of drops and every drop is going to be in its own grid grid cell and the drop is gonna stick on the window and then this kind of lie down and is it gonna stick in a new spot and it's gonna slide that so let's make this grid so for that I'm gonna go I'm gonna make UV coordinate and that's gonna take as an input DV coordinate that I get from the from the vertex shader and then I'm going to multiply that by a value that I'm going to Expo that I'm going to expose to two people working inside of the inside of the inspector so for that I made this underscore size thing over here and I'm gonna go over here I'm gonna make that and then I'm gonna also add it inside of the properties block up here some size and I have to add a label and then I have to say what type of data it has it's just a number so that's float and then let's just set it to one for now and all right so that's so that's that and now now that I've multiplied that by some potentially larger number I'm gonna take the fractional component of that to get repeat in my on my screen so I'm gonna call it GV and I'm gonna take the fractional component of my of my UV unless there's visit visualize this so that we see what we're looking at here so if I save that so now I have a bunch of repeated boxes here and I can if I go into the into the Settings here I have this size parameter here that I can change to to change how many boxes I get all right great so now these boxes they have their origin in the lower left corner I don't want that I want the origin in the middle so I'm just going to subtract 0.5 from that so now the origin is in the middle of each box and then the next thing I'm gonna do is I want to make these boxes higher than their wide so that's so that when we have a drop in if there's a drop can slide down properly so for that I'm going to make a float to here call it aspect which which gives me the aspect ratio of the box actually it's probably the inverse aspect ratio because I'm gonna say okay squeeze my box twice or by a factor of two in the X direction and in the Y direction leave it the same and now if I multiply this here by the aspect you will see that all my boxes just got squished like that so so now the box is twice as high as it is wide and let's just draw some outlines on these boxes so that we can easily see what we're doing so I'm going to say if G V dot X is larger than point 48 or GV dot y is larger than point 49 then make it a nice red color so red would be this and so let's have a look at this okay and the reason why that is is because inside of each box my origin is in the middle and the box goes from minus 0.5 to 0.5 over there and this just says if we're closer to the edge then well if my edges at 0.5 then if I'm really close to the edge to the X edge or to the Y edge then just make it a red color so so now we can just get rid of this and we still can look at what we're what we're working with okay so now I I will start drawing some drops in here so flow drop equals smooth step and because we're gonna use this smooth step a lot I'm gonna actually make a define for that so we're just gonna copy that I'm gonna go over here and over here I'm gonna say define s a comma B comma T smooth step a come on become T and that just makes it that I don't have to type smooth step each time I could just type this what this defined does is kind of like a smart way of doing a search and replace so if you define something than what you're telling unity okay before you compile the shader search and replace every time it's a smooth step with this pattern after it replace it the other way around every time it says s down here and the code with this pattern after it it will replace it with smooth step with the same pattern so just a fancy search and replace but it just makes it a lot faster to to write stuff because now I can just go s over here and if you're gonna use that 20 times you're gonna save some time so let's draw a drop and I'm going to take the length of GV so the length of of G my GV coordinate is just the distance from the pixel that we're in to the center of the box that the pixel is in so let's see what that looks like plus equals drop okay and now you can see we have a little drop in the middle of each box but to drop is stretched and that is because it's inside of the box that's also stretched so in order to to undo that we have to like undo this multiplication by aspect by dividing it by aspect over here so now we have a perfect round dole drop okay so now the next thing is we want to make that drop move and so yeah so we're trying to make it that the drop sticks to the window and then it slides down and then it sticks to a new point and then it slides down so for that this is going to get a little bit more complicated so let me just cut this out and call this drop pause I'm gonna go over here call this drop pause okay so that didn't change anything and now in order in order to move that drop what I'm gonna have to do is over here I'm gonna subtract a position from my GV I'm gonna subtract X comma Y and then I have to make my x and y so let's just set them both to zero y equals zero so that shouldn't change anything because I'm just subtracting 0 on 0 but now I can move my drop around so now I can for instance to move to the right I can just do that and what I'm gonna do is I'm going to make it that the drop goes up and down inside of its own box so for that I could just do the sign of of T of time so any time you animate something means it's a function of time so that means that we have to involve this time dot time dot y so unity gives me underscore time that's just part of unity which is the number of seconds that have elapsed since you started pressing play on your on your scene so and then this is a structure that has X Y X Y Z and W and they're just the times that go at different speeds and the time dot Y is the time value that increases by one for each second so now we have T so now I don't have to write underscore time each time and so now if I stick that into a sign and then my sign is gonna go from 1 to minus 1 but my box goes only from plus 0.5 to minus 0.5 so so we'll go out of the box if I do this if you if you see here now now it's gone and I just crossed us through the box so I have to multiply this by some smaller value in order to have it visible all the time so like 0.5 let's say so now it goes from the top to the bottom from the bottom to the top but I I want to have it that it goes down fast and then it goes up slow and for that I came up with this if I go to desmos so right now we just have the sine of X which goes up and down like that and I just came up with this so this is just me playing around on on decimals until I get something times 0.25 so that's the formula that I'm gonna use and so now this one goes up fast and down slow so I can just put a minus in front of that to turn it around so let's use that so here I'm going to do the sine of T plus the sine of T plus the sine of T times 0.5 and then I'm gonna make it negative because I want it to go down fast and up slow so now it's going up and then boom it goes down fast okay now the next thing I'm gonna do is I'm gonna make it that the entire grid moves down at the same speed that this dot moves up okay to counteract the movement cuz obviously we never want drops going up on the window so for that I'm gonna go over here I'm gonna say UV dot y plus equals time times some some value to tweak it so it goes exactly the same speed okay so now I have boxes that go down and and my drop stays more or less in the same spot and then like if it still moves a little bit you know as long as it still moves down and I guess I guess that's good but you could you could tweak that all right so now we have that now the next thing is we want to make it that this drop leaves a a little trail of smaller drops when it falls down and actually before I do that let's make it that we can scrub time so that it's kind of easier to test while we're building this so instead of this over here I'm just gonna add something to this here so if I do that then I will just know out the time and then I'm gonna do plus underscore T and that's a time value that I'm going to expose to the outside so that so that we can scrub the time so I'm gonna go over here I'm gonna add that T time and then that should be okay so let's see what that looks like okay so now it's stopped because I I just multiplied my time here by zero and now I have a time value over here that I can that I can move around to kind of scrub time myself which is which is easier for when we're building things all right so so the trail of drops so let's go leave yourself a little bit and let's go over here and let's copy this entire thing and then here instead of a drop boss I'll call it trail pause trail pause and down here I'll call this trail trail pause okay and now let's make it that we have one drop that is stuck right right in the middle so for that let me just set that to zero here so so that my trail drops don't don't move up and down so now if I add this cold plus equals trail and also let me make them a little bit smaller those trail drops so let's say three and one look okay so now we have one little drop in the middle that we want to turn into a string of little droplets and so for that what I can do is over here so right now my trail pause it goes from 0.5 at the top of the box to minus 0.5 at the bottom of the box so if I do this and tropopause y equals y times 8 let's say so now might show positive Y will go from plus 4 to minus 4 and now I'm gonna take the fractional component of that so BRAC so that will just slice the the space into into a bunch of different boxes the same way that we slice the space into two boxes that you see over here let's have a look at what that looks like so save that so now we have a bunch of drops but they're all very squeezed and that is because we're multiplying by 8 over here well that means that outside of the fret we have to divide by 8 in order to get rid of that distortion so do that and now we have a bunch of drops but they're all cut off halfway and that is because when you first do a frac well the the the origin is gonna be at at the at the edge of the box so similar to how over here we have to subtract 0.5 well over here we also have to subtract 0.5 so but before we do any divide by 8 here so [Music] okay so now we have a bunch of little string of little drops but there's one problem with this which is that when I scrub time you see that those drops like they mean they move with it with the red boxes and obviously when it leaves a trail drops we want we want those those trail drops to stick to the window to the same spot well for that I could just use the same offset that I use over here we could use use that inside of the Y over here to cancel out that movement so now if I go over here and I move this you see that those drops they stay in the same place all right now the next thing is to make sure that there are no drops underneath the main drop right because we want to make it the main drop kind of deposits those little those little drops so we have to yeah we have to mask that out and how we do that is is by multiplying these little drops by a number that is 0 for every pixel underneath the main drop and it's one for every pixel above the main drop so then if you multiply something by zero it's gonna cancel it out if you multiply it by one it's gonna not do anything to it so for that I'm gonna go over here and I'm gonna multiply my trail by some function at a zero or one depending and for that I'm gonna use a smooth step and we can realize that the the drop pause over here is going to be negative underneath underneath the for every pixel underneath of of the main drop and it's gonna be positive for every pixel above the main drop so we can use that so if I go over here and I say drop us not Y and then let's say - point zero five comma point zero five so what this function will do now is everywhere drop pause is smaller than - point zero five it's gonna return zero everywhere it's above point zero five it's going to return one and anywhere in between it's gonna it's gonna do some smooth interpolation between it too so let's see what that looks like and I'm gonna have to scrub my time so you can see actually yeah so now you can see that that there are no drops underneath underneath the big drop okay so the big drops kind of deposit of little drops okay the next thing I want to do is I want to trail off these drops so that towards the top of the box they get less and less and for that I could do exactly the same thing so 300 times equals and now we have to make a function that is zero at the top of the box and that does one where to drop is okay and so for that I'm going to use the gvy because my G V del Y goes from 0.5 to minus 0.5 and so I know that the top is 0.5 and and now I need to figure out where to drop is well the drop is at height of Y so if I do this then this just gives me a gradient from 0 all the way to 1 and then it stays one after after your draw so let's see okay so now we have now we have a nice faded drop all right so the next thing oh yeah so we can do so this drop right now is totally round I mean it's a very minor thing but I wanted to do it anyways so the drop is very round right now but if it's stuck on the window then it you would think that it would be sagging down a little bit so for that what I can do over here is I can I can draw this disc drop at a different height for every X for every column right say if I did this for instance plus equals G V dot dot X then I would expect it to skew because my G V dot X is negative over here so meaning that it would draw to drop lower on this side and then as you go towards to ride it for every for every column a draws at high an iron higher and higher that's why this just does that and so you can take the absolute for instance and then you can kind of see how you could shape stuff like this so now it goes in positive directions or like in both directions it moves two moves that are up higher but obviously I don't want a kink in it like this so what I'm gonna do is I'm gonna make a parabola out of this so I can just do GV x x GV X and then it will make a nice round change so and then I'm gonna make the SAG the other way around so it's it's kind of minor but it shows you like kind of the power of what you can do so this is the difference between a round drop like this or a saggy drop like that okay anyways minor stuff the next thing I'm going to do is I'm going to yeah like I want to make it that this drop like doesn't go straight down but sometimes it has a little wiggle as if there is I don't know some grease on the window or something like that and for that we can just use this use this X over here right because I if I if I do that then I can move it left and right and and actually before we get too far in that like just notice that that sag that we just did on the drop you need to take the X in to account for the sag as well because otherwise it's just gonna distort more and more as you get away from the center so for the sag to properly work I would have to go minus X over here and minus X over here and then the SAG will just move with the X so I could make this a sine wave and then you would have a drop that goes down like that but I want it a little bit fancier so what I came up with was something like this so let me just so if I take a sine wave and I let's say make do that to some power to the third power fourth power fifth power sixth power so what I did is do it times the sixth power and then multiply that whole thing times 3x I mean they're like there's different ways you could do this but this is what I came up with so so well like and you've got to imagine just vertically so imagine the drop goes down and then it has a little wiggle and then it goes down and has a little wiggle the other way so let's implement that so I'm gonna go over here the sine of and then we have to think about what we're gonna throw into this sign because if I just throw this u V dot Y into it then then my wiggle is gonna move downwards with with all the boxes which we don't want we want that wiggle to stick to the to the window at the same spot so for that I'm going to use I dot u e dot Y and let's just stick that out over here and make a variable for that and then also I will multiply it so that I have a few more wiggles otherwise it's it's it doesn't change enough so I'm gonna do three times W times the sixth power of just sign of W [Music] okay and now the with the XS the same as with the Y over here I have to multiply it by some smaller number so that it doesn't go outside of the box so let's see what that looks like okay so now we have a bunch of very Wiggly drops but you can see that okay it does it does a little wiggle then it goes straight and it does a little wiggle then it goes straight and so on so forth okay maybe maybe this is too much so we could go yell at me like I guess it's I guess it's okay so this this maybe looks a little bit better so it's straight and then I does a little wiggle and then it's straight again all right so now the next thing I want to do is obviously these drop shouldn't all go all at the same time and some sort of synchronized swimming competition so what we have to do is have two like we want to offset them for each box in a different offset and the first thing I need for that is I need a different number for each box so I need first of all I need an ID for each box so that we know which blocks were in so for that I'm go over here say float to ID equals the floor of UV and let's just visualize that real quick so let me go down here let me null out all the color so everything's black and I'm cold dot are g equals ID and let's look at that okay let me just multiply this by some smaller number okay that should also go up and down let me see here why why not it's not the case okay let me just okay so like now you can see that every every box here has a different value and now we can use that value and turn out value into a random value that we use to offset the timing so let's make a function that can take two numbers as an input so and it returns a a pseudo-random value as an output so I'm gonna go over here flow to P and let me just rewrite it down so frac p times 2 so I'm just gonna take this number and multiply it or take this vector to it multiplied by some other vector - that is large so that now look like the position is very large and now we take the fractional component of that so now this P is somewhere between 0 and 1 and now I'm going to do p plus equals the dot product of P and P plus some number and this is just mmm this is just some mathematical screwing around our transform of some mathematical transformation that is so complex that that we can't see the pattern afterwards even though there is a pattern we can't see it and therefore it looks random to us there are different ways to make random numbers it's maybe out of the scope of this video right now so I'm just gonna write it out why okay so let's just test this let me see how good my random numbers are so Col plus equals M - 1 and I'm just gonna throw to you B coordinate let's say into it so I expect to see some some wide snow okay and I see some snow and so it's always good to test this to see if it looks around them enough because sometimes it sometimes it doesn't and also another thing before I forget is that this T value over here that would just increase and get bigger and bigger and bigger and because this is a floating point value floating points have have their precision goes down as the number goes up the precision goes down and and like you might get some issues with this let me see if I could show that so if I take the UV instead of either UV let me see okay so now that changes because my UV changes let me take the ID actually ID okay so now I have a bunch of random pseudo random values but if this number get like so right now it looks like it works okay it works pretty good I don't really see a pattern so that's good but if this number got really really large so let's say you've left this running for like five hours then I I might have a number that is that large okay maybe that's not large enough yet okay so now you can see if you get too large then then my random function or my pseudo-random function doesn't look terribly random anymore see like at some point you start seeing patterns and to combat that what you want to do is you want to make sure that you wrap this number around so that never can get too big so I'm gonna go over here and then I'm going to go and that's an wall so that's for the that's for the pseudo-random number but there are other issues as well if you if you have a number that's too large that's that's stored in a float it's not going to be precise anymore and then what you'll get is let's say stuff start stuttering it like it does move smoothly anymore if it doesn't look or it doesn't look smooth anymore and that's usually because your numbers are too big so let me just say okay just reset every two hours so every roughly two hours it well two hours would be that it just it just resets so that we so that we never get numbers that are large enough to kind of screw up everything all right so now we have a random number for each box so let me just zoom back in and now we could use that random number to offset our to offset the drop so let me just go back to the drops so now that I can do over here it's gonna say float n for noise is an to one and I'm gonna throw the ID into it and so now this gives me a pseudo random number between zero and one and now let's offset the time for this for the for the falling of the drops and for that actually did it okay so I'm using my time over here so if I go over here I say T plus equals n so now what that would do is that that the time between different boxes can change by at most one okay so you could see that like now now it looks already a lot more random but they still kind of go in waves and that is because we're throwing this number that can only at most differ by one we're throwing that number into a sign over here and over here and the phase of a sign is longer than 1 the phase of a sign is two pi so you have to multiply this at least by 2 pi to to get the full the full amount of randomness that you can get so now the timing is completely is completely around them so that's for the timing for the up and down let's also make it that these drops can go left and right so for that I could just go over here and just get rid of the wiggle for one second we could say so my end can my n varies between zero and one so what i could do is i could add n minus 0.5 to that okay so now so now this this value can go from minus 0.5 to 0.5 and then obviously i still have to multiply it out by point 45 is that correct no after so so now this goes from minus 0.5 to 0.5 and we can have a look at that without the wiggle and now we see that that like their their left and right but sometimes over here you see that 1 1 is cut off and that is because this is still too large now because yeah anyway it's too large so let's just multiply by a smaller number and now that is better and now in order to get the wiggle back let's go over here and say plus equals but I can't just add this wiggle now because because then if we have a wiggle for a drop that didn't start in the middle of the box it will wiggle outside of the box like over here so what we have to do is we have to make it that that wiggle gets proportionately smaller as we get closer to the edge of the box so for that I am going to use this x value here so right now this x value goes from minus 0.4 2.4 right there's a random number from minus point forward 2.4 and we just want to make throw that into a function that returns 0 when it's either at minus 0.4 or it's at point 4 and as it gets closer to the center it gets larger closer to 1 and so for that I could just do something like this I could say absolute value of x point 4 minus the absolute value of x so if I do that then if I throw point 4 into here then I get point 4 minus point 4 which is 0 if I put minus point 4 and eared and I get the absolute value of minus 0.4 which is point 4 and then the whole thing goes to 0 again so if I multiply this now I will have it that I will cancel out the wiggle for any drops that are close to the edge so these drops don't wiggle but this drop did the way wiggle because it was closer to the center okay oh yeah okay so the next thing would be to have I wanted to these drops that they cut a like I want that there is fog on the window and when there was a drop it kind of cuts a trail through the fog and and for that one thing the first thing to realize is that will be what I need for that is is similar to what I have over here for for the for a string of droplets so let me let me just do this bloat trail equals equals this and then trail x equals that and and now if I if I multiply my trail by the fog trail x equals trail now that didn't do anything that's functionally the same as what I had before but now I have access to this fog trail over here so let me just look at what the trail looks like bless April's trail now let me just multiply by some smaller numbers so that we can still see stuff and so let me just stop this for a second so we can have a good look at it so times zero okay so those fog fog trail like what I have right now it's all it's already got a fine one it's already pretty good in that it fades towards the top of the box and it's not shown underneath the box but obviously it needs to be cut on a left and on the right as well so for that I could just do a fog trail times an equal smooth step and then for that I can use drop pause dot X and if I did this point zero five my point zero five so now I would expect only the left side to be cut off okay so now it's only the left side cut off and now like what it obviously just know what I want but it will show you look maybe a little bit better so now if it'll be absolute now I would expect only something in the middle that is not showing and then we're just gonna turn that around so let's say 0.5 0.4 let's say okay so now we have only a trail in the middle all right the next thing is yeah so now so now we have this and now we like what we want to do is so let me just get rid of the orders here and so now what I want to do is I want to make like use this texture as an offset texture to read pixels from from the background texture so let me just get the background texture back so call equals text 2d and main text and I dot u UV v okay so that's so that's my my tip my main texture and so if I use that black and white drop texture to offset I could use that to offset this UV coordinate and let's see what that does so mmm so let me just make something here called flow to offset equals let's say drop plus trail so that's only to drop plus the trail drops and if I add that here offset then you will see that it already does something it does some sort of offset here it's just not the most beautiful offset and so let's let's work on that a little bit the first thing I want to do is I want to make this tweakable so I'm gonna I'm gonna add a variable called underscore distortion and I'm gonna multiply that my offset by that and let me just go over here and add it over there and then also add it over here I'm gonna say distortion and I'm if I'm if I make that a number that is between 0 & 1 then I could just multiply that by that number and and that will that will change my that will change my distortion and actually let's just go also negative so that we can see what that distortion looks like in both directions and then my default would be 1 okay so now if I make this a little bit larger so now I could tweak this already a little bit but again like the dis offset is not correct so so we have to work on on the offset and the reason why this looks right now is because my offset is kind of the same it's only in one direction and it's just not very good so let's go over here let's make a proper offset for this so what we would want is is that if I have a pixel over here that the art now like that the offset like the offset points in the direction away from the center of the drop and for that I could just use drop pause so if I if I do drop times drop pause actually let's just look at drop off by itself for one second so I'm through ball x equals zero called RG plus equals pause okay so like deep these are these are offsets and they are they are with respect to where the drop is so that's already pretty good so let's let's use that let me just look at the drop by itself at the main drop by itself okay and now it's hard to see stuff so let's increase the distortion okay so now now we have drops that look much much better yeah so and here you want it actually negative because so that so that it flips the sky and the ground around if you have the distortion positive then it would be more like a reflective surface so if you had a droplet of mono mercury or something then then you would want to positive but we're gonna have a negative okay so let's do the same the same trick for the trail so so plus trail all times trail pause okay and now we have the offset for the trail as well yeah all right so that's already looking pretty pretty watery so let me just turn this back on here increase the size alright so this was part 1 of this tutorial in in part 2 we're gonna add the fog and we're going to also make it that it's actually transparent because right now we have this district just with the texture which is already pretty cool but not terribly useful for a video game I imagine so so please like subscribe click the little bell icon so you don't miss one part two comes out which is going to be very soon and anyways thank you for watching and I'll see you next [Music]
Info
Channel: The Art of Code
Views: 43,218
Rating: undefined out of 5
Keywords: ShaderToy, Shader, Shaders, Shader Programming, Shader Coding, Shader Live Coding, Live Coding, glsl, webgl, The Art of Code, shader tutorial, rain, rain shader, rain on window, unity, unity shader coding, unity shader programming, window shader, advanced shader coding, transparency, transparent shader, water shader, tech art, rainy window, game development, game dev, gamedev, making a game, shader unity, shader unity3d, unity tutorial, water shader unity, water shaders
Id: EBrAdahFtuo
Channel Id: undefined
Length: 43min 21sec (2601 seconds)
Published: Sun Mar 24 2019
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.