Godot Shader Tutorial (1): Intro to Shader Programming

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments

This and the follow up part two are **excellent!!**

πŸ‘οΈŽ︎ 2 πŸ‘€οΈŽ︎ u/notpatchman πŸ“…οΈŽ︎ Jun 22 2018 πŸ—«︎ replies

That has been here for a few days already unless there are new videos please don't post again and again.
It was actually pinned there for a couple days or more.

I prefer other posts to make it to the top not the same one.

πŸ‘οΈŽ︎ 2 πŸ‘€οΈŽ︎ u/MinRaws πŸ“…οΈŽ︎ Jun 23 2018 πŸ—«︎ replies
Captions
hi everyone my name is bastion lei and I've joined forces with Nathan to bring you part two of this tutorial I will show you how to do similar shaders but in 3d now don't go skipping Nathan's video if you are only interested in 3d he will explain basics so I won't be covering those and seeing things first in 2d helps to understand them better so I hope you enjoyed this video please join me afterwards on my channel for part two the link will be in the description below so in this tutorial or this tutorial series we're going to see how to recreate this this water shader that's not too advanced yet but you can see there's a lot of detail and motion inside of it and it's all handled by the computer using shaders programs that run on your graphics card and that many blades every pixel inside of the water sprite so we're going to start with a first shader it will animate me good at but just to get started and talk about the difference between vertex and fragment shaders then we're going to go straight to the water and animate the pixels using a fragment shader and a periodic mathematical function the next step is to use a texture to deform our water instead of using mathematical functions because with math you can only do so much well with a texture you can control precisely how the deformation looks you can see you can create a much noisier effect much more profound then we will add some lighting to it just to see that you can combine your shaders with the light to denote and use what's called a normal map we will combine the two waves approach into one shader so this is the water sign plus the water texture offset and finally we'll add some shadows and manipulate the normal map to interact with the light from the shader to animate it as well to create that slightly more convincing water effect let's start with a basic vertex shader I invite you to grab the demo where you'll find the first shader and water folders on github link in the description in the water folder you'll find some textures and a base scene to create our water shaders and in the first shader folder that's what we're going to start with we'll find the good but and a little bit of interface will use to see how we can manipulate values in the shader from GD script to animate your materials to transitions and things like these but first let's start by creating our base shader all that we're going to open a Denson go to scene you can find it in first shader dancing Godot double click to open it and this one only contains a UI node a texture rectangle and we're going to add a shader to it in the node tree every element that inherits from canvas item can take a 2d shader this is true for all control nodes so UI node and all no 2ds all sprites and mated sprites etc so we're going to head down in the inspector to become the sytem section this is where you'll find the material slot where you can add a material to your object so you first need to add a material and you're going to add the shader the code that controls your image and its vertices inside the material it's clicked on the arrow next to the material on the slot and create a new shader material we're going to enter it now and you can see it has an empty shader slot so we're going to create a new shader for that when you click on the shader a shader code editor will appear and we get an error because we need to define some base coat for the shader to to run but before we start coding we're going to save those shaders as resources inside our project click the back arrow to head back to the shader material and you can click the Save button this allows you to save any file any resource as a reusable component inside of your project file system instead of having the code saved or burned inside the scene let's go to first shader dancing Godot and you can call it dancing go to material for example save it and we're going to do the same for the shader so we enter back in the shader by clicking on it click the Save button save as and it's going to be dancing godo and as we extension is already Dutch shader I'll just name it this way alright to start with we have to define these shaders type for that this is the first line at the top of the shader and your write shader and the score type and for 2d items it's always going to be canvas item and you have to end the statement with a semicolon any shader in the 2d workspace is going to start with this line then we can start to manipulate our sprite good as shading language is very close to GLSL and it looks a little bit like sea so we'll have to add semicolons at the end of statements but we're also going to write typed code meaning every function or variable that we write has an assigned type and you cannot use it in a different context it will not convert automatically but first let's talk about the built-in functions we have two that we are most interested in right now the first one is vertex we're going to use that function to manipulate the vertices of our object on the GPU the vertices on a 2d object are the four corners of its bounding box but in the upcoming version 3.1 you'll be able to create a mesh in the 2d workspace as well and to manipulate the mesh like each of the points using this vertex function so the code in your vertex function will run once per vertex on your object and then the fragment shader will run once per pixel there are many more pixels than vertices in a typical game you can do some optimizations you can improve the performances sometimes by using the vertex shader for example vertices have colors that you can then reuse inside of the fragment shader but this is a more advanced topic Oh now are just going to manipulate the vertices of our dancing Godot to make it dense a little bit more that we have a property called vertex that is an output from the vertex function it starts with the coordinates of each vertex and if we manipulate its value it's going to move it vertices on the dancing godo so let's type vertex it's in all caps and we could write equal vertex plus we're going to add a vector to so you use the back to constructor to define it and we're going to define it as enough set of one point zero on each axis one unit and finally we're going to add a semicolon at the end of every line and you can see it moves our vertices by one unit into D this is one pixel can use a larger value on the x axis for example upset ego Doe on the x axis a little more now for one we can write plus equal instead of equal to add something to the vertex can also use minus equal to subtract to the vertex position okay so that's fine and we can also animate it so we could use time multiply it by a value and this is going to move the object 1 pixels per second over time but the problem is it's moving outside of the object's bounding box because time is the value the time value since go to started so it can become very high that's why we make sure that we use a periodic function like a cosine to loop the animation of the object instead of offsetting it over time like to infinity we're going to increase the size of our vector yeah and you're going to see our object move in diagonal in this case so if you want to move an object or a texture or anything in diagonal you can use cosine or sine to move in one of the two main diagonals then if you want to make it move in circle use a cosine on the x axis then if you want to move the object separately on the x and y axis to make it move in a circle you can do that by using a cosine on the x axis and ay sine on the y axis now we can access the x axis of our vertex VX holding it by adding a dot and then using the x value so you can slice a vector using X Y Z 4 V coordinates and you can also call these RGB or colors but this is kind of syntactic Shigure RGB + x/y/z access the same thing the XY and z components of the vector so the problem now is we are assigning or trying to assign a vector to value to was now only a floating-point value because it's only the x-axis of the vertex so let's remove that back to 2 and only multiply the cosine by a floating point value now we're going to duplicate the line works just like the good old script editor control B and we'll replace the cosine with a sine and we're going to manipulate the y-value of the vertex property we are offsetting the vertex position of our good but over time using a periodic function - it's cyclic it's always going to move in circles in the same way we can randomize the effect per vertex by adding the vertex coordinates inside of our periodic functions you could add vertex X to the X component and vertex dot Y to the Y component to offset the effect of the periodic function per vertex can see the motion changes quite a bit you can also try different combinations like adding the vertex x + y / vertices to make sure that you get a different value on every axis so you add both x and y or the cosine on the X component and you add the vertex x + y on the cosine for the Y component this is a cheap way to randomize a value per vertex and we'll see that we can do that per pixel as well in the fragment shader but there you go we have our dancing go toe let me comment out the two lines of code to stop the animation for now and we're going to see another essential part of shader programming adding properties that you can manipulate outside the shader from GT script for example to control the speed the look whatever you want inside of the shader it's a little bit like exported properties in GT script except for shaders these are called uniforms so outside your vertex function it can declare uniform variables so you start with the uniform keyword it kind of means exported it also means that the value is going to be available in all functions in the shader so in the vertex and later the fragment or the light shader then you're going to write the type of the value so let's start with a floating value that we'll call time factor to control the speed of our animation you can give it a default value and don't forget the semicolon at the end of the line so the time factor we're going to use inside a be periodic functions to multiply the time value to make the animation faster or slower then we want to replace that static 20 pixels offset by an amplitude value for example so we're going to create another uniform this time it's going to be vector 2 value and we'll call it amplitude to control the amplitude of the motion separately on the x and y axis we can give it a default value of 10 and 5.0 for example to make sure that we see that we had different values on the X and y axis I'm going to uncomment two lines here and we can multiply the time by time factor so as it is one for now it's not going to do anything we can change the default value here by on two for example you slow down the animation instantly and then we're going to replace the amplitude value at the end with amplitude X for the X component of our vertex shader and amplitude Y or the Y component to get a much larger effect on the x axis that done on the y axis pour the time factor let's use something a little higher to see a motion go faster alright so now we've changed the values inside the shader but we can change them outside the shader and that is what your material is all about as we save the material inside the file system you can double click it to open it inside the inspector and there's a category called shader per Ram click it to unfold it and you will find the two values we created time factor and amplitude so right now they are not defined meaning the shader we'll use with the default values we defined in it but if you said the time factor to 3 it updates instantly that's also an advantage over modifying the values inside the shader because it updates much faster we can set the amplitude to a much higher value to see go to jiggle like crazy and modify them anytime and the thing is you can then save these values when you save the scene or you save the material get included inside this resource you can also create variations of a shader by modifying these parameters and saving your resource as to have the same shader with different color variations etc so this helps to make shaders more reusable in your game projects so we have those exported values those uniforms and now there are properties of a material so we can control them from Gd script that's the next step let's go back up to the first shade of folder you'll find an interface subfolder with an amplitude controller this little widget has a slider and that's in a container where you can move the slider and we're going to make it so the X amplitude text updates to show the X amplitude value the slider in Godot it's a base UI component that's clickable you can click and drag to edit the sliders value right now and the range value of the slider it has a value between 1 and 20 and it goes in one pixel increments or in increments of 1 and the start value is 15 can change the value to see B slider update now we're going to funnel the value from the slider to the amplitude controller which is the entire widget and it has to store the amplitude value etc and it will send it back down to the label to update it so we need a script on the amplitude controller so select the node add a new script are going to add it to the interface folder and call it amplitude controller I tend to use lowercase for scripts as there are slaves on extends the node and scene let's create this and we're going to remove almost everything we want to connect the sliders a value change signal to the amplitude controller select the slider had to be no tab of all click value change and double click amplitude controller when the sliders value changes we're going to update an amplitude value let's create a new amplitude very variable to store that it's going to be a floating point values and let's start with a 10 point oh for example and we're going to use a setter to update it so we're going to use a function all that you're right said gets followed by the method name the convention is to use set amplitude we only define a set of function a function called sender bleated that's going to be called every time we write something like self dot amplitude is equal to in this case the new value on the slider and we have to define this function as well let's create set amplitude the setters always get a parameter called value you have to use it we have to assign the value to the variable otherwise the amplitude variable will not change and then we're going to use that setter to do a few other things so we're going to set the text on the label when we change the amplitude value and it's going to be label start text plus a space plus we're going to add amplitudes converted to a string using the STR convert a floating point or an integer value to a string and we have to define the label start text here so let's add a new variable it's going to be on ready because we need to access the text from the label in to grab label and store the text at the start of the game and finally we're going to emit a signal every time we change the amplitude because we make a change on the interface and we don't we want to receive that change we want to put it inside our shader inside our dancing the door but we don't want to do this directly from this as it would couple the interface and be sprite to do this little more cleanly we use signals and we're going to call it amplitude changed and it's going to take the amplitude value and finally we can emit a signal when we change the impute in the set amplitude function we're going to call amplitude changed and we're going to emit the value in this case or the amplitude variable note that to use the setter function from within this script you have to use the explicit self dot amplitude meaning I want to change the amplitude value on this instance and only if you do it explicitly like that well it's called the setter function otherwise you will just write this just amplitude equals value it's going to ignore your set amplitude function so make sure that you have self before it okay that's it for the interface so now every time we update the slider it's going to update the amplitude container we can see that in the editor by adding the tool keyword and the top of the amplitude control script save now we've got to add a script to the slider with the tool keyword as well for it to update so we're going to add it to the interface folder create a script called slider Gd it's going to be empty it will just have the tool keyword at the start and has to extend the slider class okay so let's close reopen the amplitude controller and we're going to change we value you'll see the label updates as well now we have our interface setup I will close those scenes go back one folder up to the first shader scene where you have both the Denson Guto and the interface bit so we're now going to see how to get parameters from the shader and also how to modify them based on the interface but just in general how to update them from GD script select the dancing Godot we're going to give it a new script and I'll use the snake case all that as usual so dancing Godot crave the script remove almost everything and we'll start by getting the value from the shader so for that let me create a new variable I'll call it amplitude set it to grab the value when the is ready if I go to the inspector and go down to our material in the canvas item category you'll see that there's a property called material that holds this and so we can access that directly so we'll call our material and it has a method called gets and is called shader and it's called param lets you grab a shader parameter get a value from it and we can get our amplitude so you have to pass in the name from the our meter if I enter the material and however the amplitude it will be amplitude as you can see shader parameters note that as this is a property like any other in the inspector can also use the get method directly to get the value so when you do that you use the path to the property you could use material get or simply get and then enter the path to the string property which case it would be material slash shader param maybe slash amplitude that's another way to write it it's a bit like getting a note in Godot a properties can be accessed in the same way alright so now we get our amplitude we're going to print it and just do some checks on it so let's add the ready function that will be run after everything that has the unready keyword and in the ready function we will print our amplitude now in this example I've already set it to five five but by default the amplitude or any parameter in the shader can be null and if the value is null you may have some problems when you start to use it - one thing you can write is use an assert statement to make sure that a condition is met you can make sure that amplitude is not no okay and if the amplitude is null if you haven't set the value in your shader this world trigger an error in the console when you run the game but for now let's just print and press f6 to play the current scene you should see the value five five print in the console okay so we are getting our amplitude now we want to update it when we move the slider in the scene or that select the amplitude controller the interface bit go to the new tab and we find our amplitude change signal so we're going to connect it to the dancing goat oh it's going to create a new on amplitude controller and that you changed like connect to crate it access the script and now we're going to get a new amplitude that I'll call amplitude X because we are only getting a value on the x-axis the slider has only one value right so it's floating points or an integer value and now we can use that to update our amplitude variable we're going to set the amplitudes x component to our new amplitude X or we could call the parameter value as well by the way can call it however you'd like all that matters is that you have the right number of parameters when you get a call back from a signal so we set the amplitudes x component to that value and then we're going to get our material again and set the shader parameter this time we need the name of the parameter amplitude and then assign it a new value we'll use our new amplitude vector two and also copy the print statement so that you can see in the console that this function gets called when we move the slider I'll press f6 to play the game again and here if you click and slide the slider you'll see the shader animation gets bigger or smaller and in the console you can see the new amplitude value print it on every tick so this is very important when you want to animate your shaders or make them react to things that are happening in the game increase a color and the intensity of a shader motion if you use a shader to move grass and trees in your game for example you may have a global wind value that you modify based on your weather system and that then takes control of the grasses animation and all that
Info
Channel: GDQuest
Views: 93,316
Rating: undefined out of 5
Keywords: godot vertex shader, vertex shader godot, godot shaders, godot shader tutorial, godot shader, shader programming, shader programming tutorial, godot 3 shaders, shaders in godot, gdquest, godot 3 shader, programming, vertex shader, gamedev, shaderscript, open source, vertex shader and fragment shader, 2d shader, water shader, shader tutorial, vertex shader opengl, water shader godot, godot 3, vertex shader tutorial, game development, gdquest godot
Id: xoyk_A0RSpI
Channel Id: undefined
Length: 23min 8sec (1388 seconds)
Published: Wed Jun 20 2018
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.