Creative Coding with Canvas & WebGL Shaders Example: Introduction
Transcript from the "Shaders Example: Introduction" Lesson
>> Mathew DesLauriers: So what I'm gonna do is I'm gonna go back to my terminal, and I'm going to hit Ctrl+C to stop that process. And I'm gonna create a new sketch. So this one I'm gonna call shader.js. Again, I'm gonna do --new to create a new file, and then I'm gonna do --template=shader.
>> Mathew DesLauriers: And now what should happen is if we reload our page and just see 9966,
>> Mathew DesLauriers: We should have this sort of gradient-looking thing. And I'm gonna just open up our code that we just created, so it should be in the same folder as the rest of your stuff.
>> Mathew DesLauriers: So there is a few new things here, one thing you'll notice is that there is no three.js. And you can us three.js to create shaders, and to create these kind of images. But what I wanted to do is just focus this example on just purely the code that makes up the shader, the GLSL code, and try and create images just using shaders.
[00:01:23] Because actually there's such a sort of big, complex world to shaders. You can use them on meshes, and you can create really interesting patterns and surfaces. You can also use shaders to manipulate the way a mesh actually looks. Instead of making it a sphere, you can make it a really bumpy sphere, you can make it a really sort of parametric-looking thing.
[00:01:42] And so it's really, really powerful, but it's such a big topic that it would take at least a couple days to start to cover it all. And so what I wanted to do was just focus purely on the shader code, just get us a bit familiar with the syntax, because it's a bit of a different syntax.
[00:01:58] And so at the very top of our program we have CANVAS-sketch, and then we have a util/shader. And this is a utility that I like to use to just get really quickly started with a full screen shader, just like this. And then we have this thing called glslify.
[00:02:18] And we're gonna get into this in a second, but this is basically a module and a tool that we use to write shaders, just like we're writing the rest of our program. Cuz you'll notice, so far during the day we've been requiring modules, we've been getting utilities from NPM and stuff like that.
[00:02:55] So just like we're importing other utilities, whether it's color palette or something like that. Because of this, we're gonna end up being able to import utilities. You don't really need to use this yet. You could just go without using it for the first exercise. But we will probably be using it a bit later, so I'll just keep it here for now.
[00:03:16] And then we have our settings, they're pretty familiar. You just need to make sure you specify webgl instead of using 2D, cuz we're now using WebGL canvas, and you make sure it's animated. Then here we have our actual shader code. And so two things you'll notice. One is that it's a template string, just es6, this allows us to do multi-line strings.
[00:03:39] And then the other thing is we're wrapping it inside of this GLSL. And if I was to delete that, it's still gonna work fine. And so really GLSL, this utility glslify, it's really just gonna be useful when we start to bring in modules and put them inside of our shader code.
[00:03:58] But we're not doing that yet, so whether or not you have this function, it's not gonna make a difference, it will just be handy later on. And then, if we just skip this string for now and we just come back to it, and then we have a sketch function.
[00:05:08] And this is from an extension, there's a couple extensions that I have in VS Code. One of them is called Shader languages support and the other one is called, what is it, Tagged template strings, or something like that, in your Comment tagged template strings in VS Code. Sublime Text probably has some similar stuff, but it's really handy when you're working with shaders.
[00:05:33] You just put a comment saying glsl, and then any string after it is gonna get syntax highlighters. And I'm just doing that mainly for you guys to see and understand this a bit better as we code. So if we try and dissect this, we have some variables here.
[00:06:14] And it gives us the UV coordinates of the surface that we're drawing into. And then here we have a big bunch of stuff, and I'm just gonna replace this with nothing for now. We're gonna start again, just so that we don't have to dissect whatever that code was.
[00:06:28] So if you don't have anything in your main function, main function is where all the sort of pixel manipulation comes from, and every shader has to have a main function. And remember, the point of the shader is to define what is the pixel color. So let's start by just making everything white.
[00:06:48] And it looks like this. We have FragColor, which is a very special built-in reserve word in shader languages, or at least in this shader language. And we assign that to vec4[1.0]. Something that's really important, that's really annoying and really important. If I was to open my console and then I was just to put in, maybe it will work here.
[00:07:14] But in some cases, and we'll probably get into this later, but in some cases you're gonna get an error where if you just put a number without a decimal point, it might error out. And that's just something to be really mindful of. So if you have an error in your code, just check to make sure your numbers, they have to have a decimal point if they're a floating point number.
[00:07:39] Cuz if you don't have a decimal point, sometimes the language will interpret that as an integer and that will create an error. So just, that's one thing to keep in mind. Okay, so if you got this far you'll have a white background. And we're just gonna try and decipher this sort of data structure and create something that's red by using instead of a single value in the constructors.
[00:08:04] Cuz remember, when you use a single value, it sets that same value for all the different components. And if we set it to 1.0, 0.1, we should end up with a pure red background. And what's happening is that we're using a four component vector, where it's red, green, blue, and then alpha, the opacity of the canvas.
[00:08:27] We can set that to a different value, and we're gonna end up with a darker canvas. So usually, we wanna use alpha of 1, just means full transparency, and we're using vec4 because FragColor is a RGBA value. Just like in CSS, we have RGBA, and then you can specify different values you might be familiar with, I'll just write here.
[00:09:16] So it's red of 1, it's basically just like saying red of 255. Makes sense? Okay, so the first thing to try and do here is to, say, I wanna make a gradient. So instead of using these three components, which is red, by doing r 1, g 0, b 0, we're gonna replace this with a vec3, and inside of that vec3 we're going to set the UVcoord.x.
[00:09:48] So just remember that vUv is pointing to a vec2. And when you have a vec2 or a vec3, vec2 means it has an x and y coordinate, vec3 means it has an x and y and z coordinate, and vec4 means it has x, y, z and w. And so because this is a vec2 we can do .x or .y, we end up with that gradient image.