GODOT TUTORIAL : 2D Reflective water shader

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments

Really great tutorial! I'm sure lots of people will find this really useful.

👍︎︎ 1 👤︎︎ u/neotropic9 📅︎︎ Jul 04 2020 🗫︎ replies

Thanks for sharing!!!!

👍︎︎ 1 👤︎︎ u/daviddelamo 📅︎︎ Jul 04 2020 🗫︎ replies

I didn't know I needed a Roll Safe Godo-kun in my life until just now.

👍︎︎ 1 👤︎︎ u/partymetroid 📅︎︎ Jul 05 2020 🗫︎ replies

Just what I was looking for. Thanks for sharing

👍︎︎ 1 👤︎︎ u/drxwat 📅︎︎ Jul 05 2020 🗫︎ replies
Captions
hello everyone and welcome to this brand new tutorial where I will teach you how to make 2d reflective water in the ghetto engine using shaders to follow along this tutorial you will need to have some basic knowledge about shaders you can check out my previous video on how to make a shockwave shader in Godot where I explain the fundamentals of shaders at the end of the video we will have something that looks like this and hopefully you will have the skills to modify it and tweak it as you want so without further ado let's get right into it okay so here in guro I have a simple 2d scene with some background image that comes from one of my unfinished games and I add a sprite node I rename it to water and then I give it a texture I will just use the default Godot icon now under material we define a new shader material and in here we create a new shader so as last time we tell you though what kind of shader this is so we type shader type and canvas item semicolon next we define the fragment function so we type void fragment parenthesis and curly brackets so we want to sample the screen texture above in an area of the same size the local UV and the screen UV are not the same we want to know what's the height of our sprite in screen eerie coordinates for that we need to calculate a scaling factor that links the two so we take the unit height of the sprite and we divided by the unit height of the screen now we can use this to offset our sampling area on the y axis so we sample what's above the sprite but as you can see it's not flipped to fix that we multiply the offset by the UV y coordinate x - indeed oh we have two handy built-ins that we can use to get the absolute UV screen UV ratio those are texture pixel size and screen pixel size they are respectively the multiplicative inverse of the resolution of the texture and of the resolution of the screen so to get our scaling factor or the ratio on the y axis we need to divide the screen pixel size Y by the texture pixel size Y and now you may ask wasn't it tetra hide over screen height well yes but actually no because here we are working with multiplicative inverses so to get to our scaling ratio we can need to do the multiplicative inverse so it will be screen pixel size over texture pixel size on the y axis of course so back in the fragment function we declare a new float that we call UV height and we set it to screen pixel size of Y divided by texture pixel size of Y next we create a new vector that we call reflected screen TV and we set it to vector screen Y V dot X colon screen UV dot y and we add UV heart x UV dot y times - okay so let's see if it's working so we set the color to the Tetra function where we sample the screen texture and we pass our reflected screen UV and as you can see it's working as it should now let's say we want to cover a bigger area so let's grab this handle and scale the sprite as you can see it starts displaying no sense I guess so that's because our shader isn't aware of the scale of the sprite so we need to fix that in the shader we create a new uniform that will be a vector and we call it scale next we attach a script to our water sprite and we set it as a tool script so this script will be executed even in the editor next we connect the item range signal to the script so this will be executed when the rectangle of the object will be changed so for example when we scale it when that happens we want to pass our current scale to the shader so we type material dot set shader Parham and we give it scale as a string so that's the name of the property and we pass it scale so that's the current value of this pride scale now to get the tool script working we need to reload the scene so I just close it and reopen it in the shader on the reflected screen UV line we want to multiply the UV dot Y by the scale dot Y and as you can see now when we scale the sprite the reflection is displayed correctly you may have noticed that I keep the zoom level at 100% that is because when i zoom in or zoom out the reflection gets stretched in a wrong way to fix that we will take the same approach as we had for the scale so in the shader we declare a new uniform that is a float and let's call it y zoom and again we multiply the UV dot y by the Y soon well we can put it here for example it's all multiplication so we don't really care about the order in the script we create a new function that we call zoom changed and this time we will pass the y zoom factor to the shader so again let's copy that material set shader parameter so Y zoom and we pass it get viewport global canvas transform dot y dot Y we can execute this function and the process for example so it will run every frame and once I save you can see that it displays the reflection correctly at any zoom level so I'm executing it here in the process function so it's updated in the editor on every frame but that's not the best way to do it so in game you should probably call this zoom changed when you know that you are changing your zoom I don't know if you have some kind of cinematic and you are zooming in with a twin node consider calling this - so it's synced up so you don't need to update it on every frame that's kind of useless in the fragment function we will replace the color by a new variable so it will be avec 4 and let's call it reflection and here at the top we declare a new uniform which is a leg for and let's call it water color and we give the editor the hint that it's a color and as you can see now in the inspector I have this color picker so on a new line at the bottom we set the color RGB channels to the mix of the reflection RGB channels with the water color RGB channels according to the water color alpha we will basically use the Alpha of the water color as our interpolation value and now as you can see when I change the color in the inspector it changes the look on screen and as I told you the Alpha is modulating the intensity so how is it mixed to create a distortion we will need some kind of noise so let's create a new uniform that will be a sampler CD and let's call it noise so as you can see now it pops up here in the inspector so we can give it a new noise texture we define it as seamless and it's noise we create a new open simplex noise that we can tweak later so a new fragment function let's create a new float and we call distortion and we set it to texture of the noise and we sampler it according to the UV times the scale and we take only the X component of it because only one value interests us between zero and one here on the reflected screen UV line we subtract the screen UV X by the distortion and right now the distortion is very small but very strong so let's fix that so we can tweak it let's create two new uniforms the first will be a vector which we call distortion scale and the other uniform is a float that we call intensity so now here we can multiply by the distortion scale and currently it's at zero so we change it in the inspector and as you can see it scales the distortion accordingly we can also multiply the whole thing by the intensity and this way we can control the intensity of the distortion good as you can see and now the whole thing gets offset to the right or to the left depending on the sign of the intensity so let's remove the intensity here and on a new line we subtract the distortion by 0.5 we have basically it centered the values around zero so now it goes between minus 0.5 and 0.5 once the distortion is offset we can go to the reflected screening of a line and here we can multiply the final distortion by the intensity currently it's still not looking good so I will play a bit with the distortion scale until I get something that I like we want the distortion to move over time so here when we are sampling the texture we add the time to the UV but as you can see now it's too fast so let's create a new uniform which will be a float and let's call it speed and now we can multiply the time by the speed and we can tweak it until we have something that we like we can also go into the noise texture and into the open simplex noise component and here change the parameters here I am changing the period until I have something I like one last thing as you can see the distortion intensity is still and is not relative to the actual zoom so what we can do to fix this is to go here on this line and multiply the intensity by our why zoom variable and now as you can see it's fixed we can zoom out zoom in and the distortion intensity stays the same last but not least is adding some waves to the surface so let's create free new uniforms that will be each float the first is wave amplitude the second one is wave speed and the last is wave period next in the fragment function we declare a new float that we call waves and we set it to the UV dot y times scale dot y as always and we add to it the sinus of the UV dot x time scale dot X divided by the wave period and we add some moving offset so here it will be the time x and the waves speed and we multiply the whole sign by the amplitude okay let's display how this value looks so here at the end we set color RGB to bec free and we pass the waves float in it and as you can see we have this wavy shape and we can control the parameters from the inspector as you can see when I change the amplitude the wave get eventually cut off at the top to prevent that we go back on this line and anti n we subtract the wave amplitude so now when I change the wave amplitude in the end factor as you can see it changes relative to the top border right now the wave mask doesn't have a proper edge so let's use the step function to fix that okay let's set the edge value to 0.1 and here we go we have defined border we can change this value and it will offset the waves to the bottom the border looks very harsh right now so we will use the smooth step function instead of the step function I will set it to zero point one and zero point one three so as you can see the top of the wave will be a bit offset from the top and the transition between black and white is very subtle but smooth the waves look kind of boring right now so let's go back to the waves line and multiply the sinus by something else so we multiply the sinus by a cosine and in it we type zero point two times you V dot X time scale dot X divided by the wave period again and we add again the time multiplicative pie the wave speed okay so the overlapping waves go in the same direction right now so I will change here the plus to a minus so it goes in the opposite directions and I prefer it like this so now it's the right moment to tweak the waves so just play around with the parameters until you get something you like now let's apply this wave mask to what we had previously displayed we want to affect the Alpha Channel so instead of RGB we write a and we remove the effect free as we are only passing one value and tada we have applied the waves so we are pretty much done now it's up to you to tweak it as you want you can add a little white border at the top and basically that's the same approach as the Alpha so try to do this by yourself I'm sure you can do it and you can also change the wave function so I will link Decimus graph where I made pseudo trochoidal wave so if you prefer that you may also use it but use your imagination and just experiment around and Decimus or in the shader editor and I'm sure you will be able to get something anyways thanks for watching I hope you learned something from this tutorial and if you want to see more things like this consider subscribing and following me on Twitter until then see you next time [Music] you
Info
Channel: Nolkaloid
Views: 8,026
Rating: undefined out of 5
Keywords: godot, engine, godot engine, shader, water, 2d, 2d water, reflective, effect, distortion
Id: 32jdNLTJ3zY
Channel Id: undefined
Length: 18min 43sec (1123 seconds)
Published: Sat Jul 04 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.