Transcript from the "Custom Shader Setup" Lesson
>> The vertex and fragment shader demos on Glitch are pretty straightforward, and you can look at those. But I think what we'll do is we'll just do a really simple exercise, just with a gradient and a cube and start to explore that a bit. And then what we're gonna start to learn is, how do we start to create patterns and create more interesting graphics rather than just gradients and very basic stuff?
[00:00:24] So if we open up our desktop again in our terminal, go onto our webgl folder, and we're gonna create a new sketch. And maybe what we'll do is we'll just copy and paste, or you know what, we'll start with a new sketch. Yeah, we'll start with an entirely new sketch.
[00:00:41] So you might need to go into your terminal window that has the server and kill that by hitting Ctrl+C. And then we're gonna open up a new server, we're gonna say, canvas-sketch. Let's call it shader.js --new --template=3. And now we can open that up in localhost. And for now we'll just create a very simple sort of gradient cube using a fragment shader.
[00:01:25] And you'll open up that file in your Visual Studio Code, or any code editor. So we'll change the SphereGeometry to a BoxGeometry. And now we have this wireframe red cube. And so now we're gonna start to change this into a ShaderMaterial. So right now we have MeshBasic, let's say, turn that into ShaderMaterial.
[00:02:06] And it just so happens that the default color of ShaderMaterial is red. So, actually, it looks like we're coloring it red, but let's delete red and save, and it should still be red. And so what's actually happening here is we've just created a Shader Material, we've specified wireframe, true.
[00:02:27] Let's turn off wireframe as well, so that the ShaderMaterial is completely empty. And what's happening here is that three.js, if you don't give it a shader, if you don't give it the GLSL code, it's gonna use a default. And the default is just a plain red material, with nothing else.
[00:02:43] It's just always red. So let's start to build up a more interesting look. So, first, we're gonna say, define a fragmentShader. And let's declare it above. So I'm gonna say, const fragmentShader. I'm gonna use these template strings. And here's a little tip, is when we're writing shader code, so now I'm writing some shader code in a string, and especially on this screen, it's gonna be better if I could get syntax highlighting inside of this template string.
[00:03:17] And so if you are using VS Code, you can open up the sidebar and check out an extension. So, here, if I go to my extensions and I search for one called comment tagged templates, If you want, you can install this, and we can start to get syntax highlighting directly inside of template strings.
[00:03:41] You would install this one, and then you'd also install another one called shader languages support. So these two extensions, this one will give us actual syntax highlighting. And the other extension is just gonna allow us to do syntax highlighting within a template string. So here, once we've installed those, we can use this comment syntax.
[00:04:08] So we can say comment, glsl, end comment, and then start the template string. All of a sudden, the code within the template string is gonna be syntax highlighted. Okay, so we're writing this fragmentShader. Right now, it's just going to be a black sphere on a black background. We can confirm this just really quickly, just see what happens.
[00:04:30] It's maybe not even rendering anything. Sometimes that's because when we look at the console, it's gonna give us an error. So if I just look at my console, it's gonna give us an error that's actually saying some stuff. It's saying some buffer format, fragment, open variable, incompatible, blah, blah, blah.
[00:04:48] So maybe what we really need to do is start to put some code into our shader here, because we just have an empty shader. So I'm gonna start by saying gl_FragColor. Let's say we'll make it 0.5 again. And maybe instead of 0.5, it's actually gonna be better to do the color red or something.
[00:05:17] And make it pure 1.0 on opacity. And we can make that blue or green, here. But we wanna do something more interesting, we wanna create a gradient. And so the way we're gonna do that is, we're going to start by getting a vertexShader going. So here's an example of how to debug a shader.
[00:05:51] If you make an error, you're gonna get this massive error log. At the bottom, it might say program not valid or no valid shader program, you'll get all this red code. And if you scroll up to the top, where this red code, where the error starts, usually, it'll say error with the line number.
[00:06:12] So this is 107. And it says syntax error, sometimes there's a little hint. So if I go to line 107, I have to actually go into this red code, scroll down, line 107, and you might actually see the error there. And then you might be able to fix it that way.
[00:06:31] Missing semicolons, or sometimes extra semicolons, can create some problems. But that's how you start to track down errors. The other thing with debugging shaders is that there's no way to console log in a shader. There's no way to set a breakpoint or anything like that. And so let's say you have some number, it's a float.
[00:06:53] I mean, here we know it's 0.5 because we're looking at the number and we're saying, okay, this is obviously 0.5. But let's say this a is coming from some sort of math, some sort of input, maybe it's like interactive or something or it's changing over time, and you wanted just to console log what a is.
[00:07:08] Well, you don't know if a is negative or positive or whatever. Well, what you actually have to do is somehow get a into the range of 0.0 to 1.0, and then place that in the color. And then you have to look at the color and say, okay, well, the output of this cube is kind of dark, or maybe it's even easier, instead of doing red, you use a gray scale value.
[00:07:30] So now I'm looking at, I'm seeing this kind of grayish cube. And so I have an idea that the value is somewhere between, in the middle range, between 0.0 and 1.0. Whereas if I was to look at it like this, I'd be like, this looks like pure black, so this value must be a.
[00:07:48] Or, sorry, it must be 0.0. This a value must be 0.0, or it might be a negative. If it's a -10, it's also gonna appear pure black. So it's very tricky to sometimes debug shaders because we don't have console.log. We just have to look at the colors and try and understand how that works.