Check out a free preview of the full Advanced Creative Coding with WebGL & Shaders course

The "Texture Coordinates" Lesson is part of the full, Advanced Creative Coding with WebGL & Shaders course featured in this preview video. Here's what you'd learn in this lesson:

Matt demonstrates how vUv values are used in texture mapping, rendering the x and y texture coordinates to create the gradient on a box geometry.


Transcript from the "Texture Coordinates" Lesson

>> So we're somewhere around here we have this purplish or some sort of colored cube with the gradients. One of the things I want to start to explain a little bit more is texture coordinates. And also how do we use this UV thing or this UV thing and what what is this UV thing?

So the first thing before I explain it, I just wanna change this color so that it's white. This will just help me explain a bit rather than thinking in terms of color, let's just think in terms of grayscale. And so, here what I've got is a pure gradient that goes from black, which would be zero.

So zero, zero, zero the color RGB zero, zero, zero would be black. To white, which is 111. So one red, green and blue is gonna produce white. And so vv.x is a value that goes from zero to one, and in this particular geometry and that cube or a plane, this kind of square type geometry, one of the sides usually you can imagine the left side is gonna be 0 and the right side is gonna be 1.

And I put that in quotes because it really depends on how we're looking at this cube. But imagine we're looking at it like this, the left side is gonna be 0, the right side is gonna be 1. So the X is the horizontal text recorded value, and the y would be the vertical.

And notice instead of going from 0 on the top to 1 on the bottom, it's actually inverted. And sometimes in WebGL the y axis is gonna be a little bit inverted. And so you just need to think sort of upside down in terms of the y axis. And so now we're getting the vertical texture coordinate.

And so this is going from 1 all the way down to 0. And this is just some value that you get inside of all the built in geometries that you can use in your shaders. And it gives you this value that goes smoothly across the surface of the geometry and it's actually used for texture mapping.

So, if you could imagine maybe this is kind of a good example, but this is one of the ways in which we use texture mapping. Texture mapping is when I say mapping it's almost like wrapping things. It's figuring out the coordinates and the numbers that we need to use in order to take an image, kind of like the earth image that we've been working with.

So this earth.jpg, how do we map this onto a sphere? How do we map this onto a geometry? That's the process of texture mapping and we use these UV coordinates in order to do that. So that's kind of why Three.js includes this UV stuff is because it's used for sampling from a texture and producing textured results.

So one of the cool things actually that we can do with just this simple line of code is just start to add in different values for each of the different components. And all of a sudden, we're gonna have this sort of multicolored cube. And what's happening here is we're saying each of these components is gonna end up with either the x or the y value.

And you could even go further than that, you can multiply 1 by some smaller, larger number. I don't know you can just play around with it if you want. But you can see how you can create these different gradients and it's because we're introducing more or less of one of the three colors.

Okay, so that's kind of little primer on texture coordinates. One of the other things that you might wanna start to do is introduce maybe some animation or some movement. A very common thing to do is to introduce a uniform called time. So here we have time, and we say time, the value starts at zero.

And then maybe, we want to manipulate these colors or even manipulate the positions by time. So we can add in a uniform float time. So this is a float because it's not a vector, it's just a number. And then maybe we'll add in for the red component, let's say vv.x is+ sin(time).

Sine is like the cosine when we're talking about sine, it's that mathematical signal for a circle sort of. And this isn't gonna do anything yet because time is always 0. It's never changing because we've just defined it here in our material, but we haven't updated each frame. So in order to update then, we're going to go down to our render loop.

We already have time here. And so we're gonna update it by saying, material, which is the name of the material we've defined just to make sure, you might need to scroll up and just make sure you're using the same name. But it would be material.uniforms.time.value = time, so you have to do .value.

So now you should have some gradient that would be sort of shifting with more or less red color. And what we're doing now is pretty abstract. It's just sort of experimenting and playing around, we don't have any goal in mind. Maybe you're just gonna be tinkering and exploring.

Maybe changing some of these colors is gonna start to look pretty cool. Maybe you could even do cos, instead of just doing sine you could do cos in one component and sine in the other. And then all of a sudden you have this kind of like circular rotation that's cycling through colors.

But still, we don't really know what we're doing necessarily. We're just sort of absent-mindedly changing values, which is a totally legitimate way to work with shaders. It's actually a lot of the time when I'm working with shaders, I'm just sort of experimenting with numbers, putting in things and seeing how that changes the result.

And sometimes coming up with these happy little accidents that look pretty cool. And then that actually ends up being the work. And that's okay if that's what you end up doing. So you could even also go into the primer, the WebGL primer if you wanted to. You could try and copy just an exercise, but we don't need to do it.

But just as an exercise, you could go into the vertex shader, and try to copy this, or some of this, into in your Three.js vertex shader. The bulk of it will be here. And then maybe you could manipulate this time, you could manipulate the stretching by time in your own program.

Just remember there's a few differences between this raw pure GLSL and the way that we write it in Three.js. The main difference is that we no longer need to write precision hypee float in our shaders. And we don't need to specify these two uniforms here. And we don't need to specify this built in position because it's coming from Three.js already.

That's just something as an exercise you could try and do yourself.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now