How To Shader (Fast) - using Godot Engine

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
Shaders are amazing. You can do really pretty stuff very easily. So in the long run, it makes your game prettier and saves time making resources. We will cover what a shader is real quick, and then teach you how to write what you need for your game. We compress hours worth of information in here, so your head might hurt a bit. You can imagine a shader as a way to teach a GPU how to draw a certain object. This was originally meant for lighting etc, but quickly became used for all types of visual effects. This origin shines through at many points, and explains why some things don't work on the GPU or are slower than you would expect. The important takeaway is the mindset. GPUs are massively parallelized. So we don't think in the scope of a whole picture, we only describe what to do with a single pixel. And this is done for every pixel. Let us start with the examples. We will be using Godot, but it works similarly for other tools. We open it, add a texture and give it a material, which holds parameters for our shader. Then we add the shader itself. To make a 2D shader, we write shader_type canvas_item. We type out a fragment function, this means we manipulate the image pixel-wise. This function has no return, but we will compute the COLOR variable which holds the color of the pixel. For a shader that just reads an image and draws it, we use the texture method. It takes two arguments: the texture to sample, and where to sample it. We can use the texture that is assigned with TEXTURE, and for the place… Well, we have to meditate on this. We remember that the code is run for every pixel, in order to tell them apart we have their coordinates within the texture. This is called the UV coordinates, and always is between 0 and 1 in both x and y dimension. We can reference our UV, with the “UV” keyword. The texture call needs such a coordinate to sample the texture. So let's just give it our coordinate first. We just get the color value we expect and can assign it to the COLOR variable. The shader will draw whatever is assigned to the COLOR variable. So now we can see what our changes do. Understanding UVs is the most important thing, and a bit of a headache at first. So let's play around. When we multiply the UV by 2, the texture is sampled more densely, so it will be smaller. The center of the sprite that is at UV 0.5,0.5 is mapped to 1,1, the bottom right corner of the texture. We can interchange this 2 with a constant, defined above here. Or with a uniform. A uniform is a kind of variable and how we get information from the CPU to the shader. It can not be manipulated in the shader and always is the same for every pixel. Let's make the 2 into a uniform. We can give it an editor hint so we get a nice slider. When we now slide it around we see that we learned to scale images dynamically. We can also do distortion-like effects. For example, by adding a part of the Y coordinate to the X coordinate. Try to play around for yourself to get the hang of it! If we ever want the graphic to repeat, we can change this in the import settings. We can also manipulate the color. Let us try and make the image greyscale. For this, we need to reference the different color channels separately. We can access the components of a vector with .r for red, .g for green .b for blue and .a for its alpha value. Alpha is the transparency of that pixel. So when we average the r,g and b value, we have a greyscale value. We can write the same value on all of the channels, and there it is! I read some people had problems with the builtin modulate, because it can not add color that is not there. It’s only multiplicative. So let's fix that. We can simply multiply the greyscale value with a color, to color that image. For that we add a color uniform, with the following line. We now can choose a nice color, and the image will change in real time. Many games also need a flash effect. For this, we just need one more uniform to decide how flashed the graphic is. Get rid of the greyscale. Instead, we now interpolate between the flash color and the current color. Luckily, this is very easy with the mix function. You say what color is interpolated towards what color, and how to mix between those two. Use the original image color, the flash color and our interpolation uniform. We can play with this slider and see the magic! The cool thing is, each uniform can be animated by an animation player or tween. So maybe add an animation player and change the flash state. It can even animate the color! When you have multiple sprites with the same material, this will change all of them, so we need to make the material local to scene. There is one more trick you need to know before we get into the crazy stuff. Swizzeling. With swizzeling we can use vectors very creatively and access the components in a really cool way. Let's say we want to swap colors around. You can write COLOR.rgb = COLOR.gbr and they will swap around. You can even use the same color multiple times, like COLOR.rgb = COLOR.rrr to write the same one everywhere. Keep in mind, this is not the same as the greyscale shader, it just switches the red channel to grey and throws away the rest! We will now do a bit of advanced magic! Fancy distortion effects such as the typical explosion shockwave are made by reading the screen itself. You can access the screen texture by writing SCREEN_TEXTURE. If we use the UV to sample it, we see the screen in small and flipped. This is because the 0,0 of the sprite is up here, and it is mapped to the 0,0 of the screen. We usually want to sample the point directly below the image, so we use the SCREEN_UV. This shader now does absolutely nothing. But we can make the same adjustments and even the same distortions. So let us distort the screen uv, for example, based on our image. If we use different images, we can get different results. We can also generate a texture for this purpose. To give it to the shader, add a sampler2D uniform. There are really helpful texture types that you can generate inside the engine. We can add a noise texture filled with simplex noise, which is basically cleaner perlin noise, with a lot of parameters. With a bit of playing around you can do cool effects with that. But it's a little complicated, so we linked a video about that in the description. There are also gradients, which are great, for example, to overlay them onto the sprite or to map the sprite’s colors to the gradient. For this, simply use the brightness and use it to address the gradient for this nice effect! And lastly, curves are great too. When given to a curve texture, they are translated into a grayscale image. We used them for this black hole for example! There are other types of shaders as well. Vertex shaders can manipulate the position of objects. They are most impressive in 3D, so we will switch to 3D. We can use the vertex function and now have access to the VERTEX keyword. With this we can take this boring plane, and add a sinus wave to the Y coordinates. We can make this shift if we want, either using a uniform or based on the time. To make it time-based we use the TIME builtin, and add it to the sinus. Now you can see fancy wave effects. You can also sample a texture in the vertex function. The fragment function still exists here. Let's add a part of the UV to the color, just to see a little gradient to visualize UVs once more! But instead of COLOR, we set ALBEDO and ALPHA. By the way, when you create a SpatialMaterial, you can convert it to a shader material. This way, you can add your own shader code to existing materials.. Shaders can be used for many many more things. You can control particles with them, because particles are more or less just vertices. We made a whole video about that. You can also apply it to the visuals of a particle and do the wildest stuff with that! We have a whole playlist down in the description with different effects you can do. If this was helpful to you, please give the video a like! If enough people are interested, we can go for a part 2!
Info
Channel: PlayWithFurcifer
Views: 261,315
Rating: undefined out of 5
Keywords: godot, godot engine, shader, 2d shader, 3d shader
Id: 1pJyYtBAHks
Channel Id: undefined
Length: 7min 9sec (429 seconds)
Published: Sun Apr 24 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.