Archive for January, 2018

Computer Graphics programming isn’t just about getting the technical stuff right. It’s also about using your eye, looking mindfully at the world around you, being inspired by the beautiful patterns in nature, and drawing upon what you see as inspiration.

In lesson 19 we start with the code we developed in earlier lessons, and then tweak things a bit to bring out a desired aesthetic quality. In particular, we change our undulating disk just enough so that it suggests the reflection of the Moon over water at night.

Note that we don’t need to include all of the details. As long as we properly suggest the real thing — through good choice of color, shape and movement — the mind of our viewer will do the rest.

Everything we are doing so far is on a flat plane. vPos.x and vPos.y vary, but vPos.z is always zero.

Yet the noise function actually takes a 3D point as its argument, and we can use this fact to create animated textures. If we animate the z coordinate of its argument, we end up essentially sliding the noise function in z over time.

You can think of this as taking different planar slices through some solid textured material. As you slide your plane through the texture, you uncover different layers of the texture, so the texture you see will change over time.

For lesson 18 we do just this. By animating the z coordinate of our argument to the noise function, we end up varying the value of the noise over time. The result is that the texture that is causing our disk to look bumpy will animate.

For lesson 17 we will apply the noise function to something quite different: Changing the shape of something. Here we start to see that noise can be used pretty much anywhere, to make things look a little less synthetic.

One way I like to think of it is that noise is kind of like salt. You wouldn’t eat salt by itself. But if you sprinkle just the right amount on your food, the food tastes better.

Computer graphics gets boring if everything becomes too regular. So it’s good to introduce a little randomness, to mix things up a bit and make the image look more natural.

But it should be controlled randomness, much in the way the arrangement of the bristles in a paintbrush allow an artist to add controlled randomness into a painting, while still maintaining aesthetic control.

To do this we can use procedural noise. Noise can be used in all sorts of ways. In lesson 16 we are using it in a very basic way: to create a simple texture that doesn’t look too regular.

In lesson 14 we start to use one of tne of the most powerful constructs in programming. The if statement operates pretty much the way the word “if” works in English: “If this thing is true, then do that thing.”

In this case, we will make the red disk appear to be in front of the green disk. We do this by checking to see whether we are inside the red disk. If we are, then we won’t show the green disk.

One nice thing about defining functions is that you can call them more than once.

In lesson thirteen we see an example of creating two disks, both calling the same function disk(x,y,r), but with different arguments.

One disk is red, and the other is green. That’s because we use them to create the color:

vec3(c1, c2, 0.1)

The red component of this color is c1, which has a high value only inside the first disk, the green component is c2, which has a high value only inside the second disk, and the blue component is 0.1, which gives us a dark blue background everywhere.

Eventually, as your program does more things, you will want to abstract out useful tasks like “make a circular disk”, so that you don’t just keep writing the same code in different ways.

To handle this, shader programs let you create your own functions, and that is what we are doing in lesson twelve.

We are breaking out the concept of “create a circular disk” into its own separate function. Then, in the main part of the shader, we call that function with the particular arguments we want.

One nice thing about this approach is it makes it easier for us to understand our own program. A circular disk shape always needs three things: an x position, a y position, and a radius. By writing code that makes such concepts clear, we end up with programs that are easier to write, easier to read, and less likely to break.

Today we are going to start making shapes — using a little high school math.

You probably learned in high school that the radius squared (r2) of a circle is x*x + y*y. That means we can use the expression x*x + y*y to measure the distance squared from the center of the image (that’s the place where both x and y are zero).

If we then apply our handy dandy step function, we get a disk shape.

Everything inside the disk is where r2 is less than our cutoff value. Everything outside our disk is where r2 is greater than that cutoff value.