How To Create A Water Shader // Godot 4 Tutorial

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
today we're creating a water Shader from scratch in the gato Engine 4 beta by the end you'll have a water Shader with customizable parameters and advanced features like vertex noise displacement and depth color to get started open up godo4 and create a new project we'll be using the forward plus renderer so make sure that's selected before we jump into coding we need to set up our workspace a little bit it's always good to stay as organized as possible so we will create the following folders in the file system tab scenes shaders and resources we'll be starting with just two scenes a map scene and a water plane scene the water plane scene will contain just our basic quad mesh plane which we can then insert into the larger map scene create two scenes map and water plane and place them into the scenes folder the map scene will use a 3D node as a parent and set the water plane parent node to a mesh instance 3D node to set up our water plane we'll open up our scene and click on the mesh instance 3D node to the right is the inspector tab that holds all of the node information find the mesh instance 3D title look for the mesh field and click on the drop down then select new Quad mesh we now have a plain mesh in our viewport area we'll need to adjust it a bit so we're ready for our Shader click on the mesh drop down to open up the mesh properties to the size to 1 meter by 1 meter then subdivide the width and depth by 200 this will create more detail within our mesh and allow for more vertices to manipulate and finally set the orientation to face y now the one by one might seem a little small and it probably will be small for your scene but we're going to be scaling this through the Shader so we don't need to scale it right now through the size of the mesh the detail of our plane is going to be happening through our subdivision and so we can scale things through that according to the amount of detail that we need next we'll create the Shader for our water plane mesh we can do that by going to the surface material override and clicking on the drop down then selecting new Shader material selecting that material and then clicking on the Shader drop down creating a new Shader we'll name this water and use the spatial mode save both the Shader material and Shader and place both of those into the shaders folder now that we've got our scenes set up and our Shader ready to go we can start coding gato provides a shading language based on the opengl shading language glsl and while it may look similar to gdscript there are differences in language and syntax the first thing we need to do is open up our water.gd Shader file this will bring up the Shader editor at the bottom of the screen and show you the bare bones of the Shader script you'll notice the Shader type which is set the spatial and the void fragment function if you're familiar with how 3D rendering works this will be our pixel Shader code So within the pixel Shader we can set the usual values like Albedo metallic roughness We'll add our first code into the fragment function to turn the plane mesh black but obviously water isn't black and if it is you should probably call somebody so we need a way that we can change that and we don't want to have to go into the pixel Shader to do it every single time so what we can do is create a variable adding a variable will allow us to edit that value within the editor and even within the script so to do that we can add what we call a uniform variable by adding a uniform variable Albedo we can set the color in the editor and pass that variable to the pixel Shader with our code set we can click on the surface material override of our mesh and find the Shader parameters tab for all of our uniform variables will show so set the Albedo color to zero zero five two six e and repeat the same variable and parameter process for both metallic and roughness now you'll notice two things I've added a hint range function and an equals for both metallic and roughness variables this allows me to set a range of possible values for the variable as well as a default value with our Albedo metallic roughness value set we can move to the more involved process of adding normal Maps normal maps are a great way to add cheap depth and texturing to a material without adding to the geometry so let's add two more uniform variables to our code only this time we'll use a sampler 2D texture variable one for each normal map to get the first normal texture up and running we can go to the Shader parameters of the mesh surface material override find texture normal and click on the drop down then click new noise texture 2D click on the drop down to open that then find noise and click on that drop down and choose new Fast noise light agato engine comes with built-in noise generation via the fast noise light library and we'll use it to generate some water like noise for our Shader our settings will go with purlin for our noise type and for our fractal type will go with ridged then set seamless to true as normal map to true and set the bump strength to 1.5 with our texture ready we can reference that within our Shader code to get the noise texture we must first use the texture function and the UV variable to get the texture and coordinates of our noise then pass that to our normal variable and then set normal map to normal we can create a second noise texture just like the first and then interpolate between the two textures to mix them both into one to do that we'll create a new variable normal blend that will mix both the normal maps and then pass that variable to our normal map value foreign with both normal Maps ready we can start animating so water moves and static water doesn't look too great so we need to add some movement to our Shader and one way that we can do that is to animate the normal Maps we just added we'll need to add some more variables to control the rate of movement and the direction of the movement then we can use the built-in time function to add to the UV offset each frame or tick so first let's add our new uniform variables for our wave direction for each normal map and then a time scale then we can take both of the wave direction variables multiply that by our time variable and then multiply that by a time scale so we can adjust how fast or how slow the waves move and with those variables ready we can add our movement Time and Time variables to our UV values in the normal blend variable and now you should have some moving water and for a really basic water Shader this may be exactly what you need and you can stop right here but if you need some more advanced Shader features let's keep coding the first graphical boost that we can give to our water is to add a fresnel effect to our overall Albedo Brunel will adjust the color of our water depending on the angle the camera is viewing the mesh the first line of code that we need is another uniform variable for our second Albedo color and a fresnel function that we can run in our pixel Shader now within the fresnel function you might notice the declared variables in the function these are called hints and are part of gato's static typing feature using type tints is a good practice as it sets what values must be used within the function and can make it easier for the editor to suggest code next you need to add another variable in the pixel Shader that will run our fresnel function and then interpolate between our Albedo and albedo2 values using our fresnel value as the alpha and finally passing the result to our Albedo value you should now be able to use the Albedo 2 color value in the editor and come up with some interesting color combinations but for this example we can use 0079c3 now we've baked texture and depth with our normal Maps but we can actually create height with our Shader by adjusting the vertices of our mesh with noise but we can't do this in the pixel Shader we need to use the vertex Shader this occurs in a different function that you can add after our uniform variables and before the fragment function for our vertex displacement we'll need three more uniform variables wave which will be a sampler 2D texture noise scale and height scale we also want to make the mesh and shaders scalable meaning the normal map and vertex displacement should occur via World position rather than the mesh UV this will allow us to make the mesh as big as we want and not have to worry about any stretching or scaling issues to do that we need to add a new kind of variable that can carry values from the vertex Shader to the pixel Shader called the varying variables we'll add two of these variables after our uniforms Heights and World position next move to the vertex Shader where we can set the world position for each vertex of our mesh with the following code these next two lines will take our noise texture and grab the R value which will be from 0 to 1 at the location of each vertex per the texture then that height value is multiplied by the height scale and added to the Y value of the vertex to raise or lower its height because we also can grab the time value we'll animate it just like we did with the normal maps with our code set we just need to generate our noise texture in the Shader parameters and be sure to set the noise texture 2D to seamless additionally now that we have a world position variable that we can use we can swap out the UV variable in our normal blend Vector so that our normal Maps also scale properly with our new Vector displacement you may also notice some dark spots showing up on the mesh you can get rid of these simply by turning off cast shadow in the geometry tab of the mesh inspector so we have fresnel and we have our vertex displacement the next thing that we can add is a depth fade this will make the water surface color adjust to how close the mesh is to other meshes beneath it this replicates how light scatters when passing through water to achieve the effect we'll need to add some more code to our Shader and adjust some of the existing code first we can add some more uniform variables these will allow us to set our deep and shallow water colors in the application of Bear's law which deals with the attenuation of light for the properties of the material through which the light is traveling in this case water your Bear's law and depth offset value may be adjusted depending on the effect you want and the overall depth of the water next we can add the following code to the top of our pixel Shader function that will get a depth texture from the viewport and apply a blend and coloration of the depth gradient and with our new depth colors we need to swap out our Albedo value again this time incorporating our new depth you should now be able to go to the map scene add your water plane if you haven't already and add a basic mesh to see the color change depending on the depth of the object the last Shader feature that we can add is an edge detection feature which will allow us to use the depth to find where the mesh is closest to or touching another mesh by clamping a range of values where the mesh is closest we can separate those pixels of the mesh and adjust their color independently giving the effect of a foam Edge the overall look of this effect will probably largely depend on your artistic needs of your scene but this will offer one way that you can achieve the effect we'll first need to add four more uniform variables in a new function called Edge the values of these variables will again depend on the look you're trying to achieve The Edge function will take our depth again and figure out how near and how far our mesh is from other meshes then we can add our Edge detection functions and variables into our pixel Shader here and then adjust our Albedo value one final time to mix the depth color and Edge color and combine that value to our surface color foreign and with that the water Shader itself is complete and you can add it to any terrain scene or level that you have the tutorial demo project contains a simple procedural terrain built with the same vertex displacement as the water and a world environment node with a high quality panoramic image for the sky if you'd rather read this tutorial than watch it you can go to the stay at home Dev website where you can also find the tutorial project files if you have any issues with this tutorial or the project files you can find me on the Discord server or contact me through the website or leave a comment here and if you want to see what I'm making in the gato engine you can check out my devlogs or my dream game thanks for watching and keep creating
Info
Channel: StayAtHomeDev
Views: 36,071
Rating: undefined out of 5
Keywords: made with godot, godot 4, godot engine, godot 4 tutorial, godot, godot 4.0, godot 4.0 tutorial, godot 4.0 3d, how to use godot, godot 4 beta, godot 3d tutorial, stayathomedev, godot water shader, godot engine water shader, godot 4 water visual shader, godot stylized water shader, godot stylized water, how to make a water shader in godot, godot shader, godot engine shaders, godot engine shader tutorial, water waves godot, godot 4 water, animated water godot
Id: 7L6ZUYj1hs8
Channel Id: undefined
Length: 13min 9sec (789 seconds)
Published: Tue Jan 31 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.