559 Graphics – Graphics Tutorials https://pages.graphics.cs.wisc.edu/559-Old-Tutorials/ Tutorials for various Graphics Group Classes Sat, 30 Jan 2021 02:10:38 +0000 en-US hourly 1 https://wordpress.org/?v=5.7.11 Getting Started with TWGL m4 (matrix library) https://pages.graphics.cs.wisc.edu/559-Old-Tutorials/getting-started-with-twgl-m4-matrix-library/ Wed, 16 Sep 2015 22:58:36 +0000 http://pages.graphics.cs.wisc.edu/559-Old-Tutorials/?p=82

For the programming assignments, you will need some basic matrix support to do transformations. You could program this yourself, but you are also welcome to use a matrix library that does it for you. Doing it yourself is good because you have to understand it – but it’s a lot of busywork. Learning to use a matrix library is a better idea, since its what you need in the “real world”.

For doing graphics, we need 4×4 matrices and the associated vectors. There are a few JavaScript libraries out there for this. glmatrix is the best known. I will recommend that you use the “m4” part of “twgl” since twgl will be useful later in the class. This isn’t a judgment on whether twgl.m4 is better than glmatrix – it’s good enough, and easy.

The twgl webpage is here. The link to the documentation is hidden at the bottom (documentation). Even then, you need to look in the upper right corner of the window to find the real things you need. The documentation for the matrix library (m4) is here – but that’s just for the matrix class. The vector class is documented separately. Even then, there are class documentation, but no general guidance on how to get started.

Hence, a tutorial.

Getting Started With TWGL

To use twgl, you need to load it in your html page (load it before your script). If you want to have it load fast, use the minified version. If you want to be able to read the code, use the other version. Either way, you need the “full” version so it has matrices.

I have put a copy of twgl on the graphics group web server so you can access it from JSBin programs. Or you can put the file in your local directory so it loads fast. For things you turn in, its best to refer to the online version – or you can turn in a copy of the library with your handin.

Loading twgl adds one global “variable” – twgl. This is using javascript objects as namespaces and modules (something to get used to as a JavaScript programmer). Within twgl, there is a field called “m4” that is another object that contains the matrix library. I find it’s easiest to create a variable called just “m4” so I don’t need to keep referring to twgl.m4.

4×4 matrices in twgl are actually 1D arrays of length 16 – not really 2D arrays. In fact, they aren’t even normal JavaScript arrays – they are special “Float32Array” which stores things so its easy to pass to WebGL (when you get to that). The m4 functions will take any array of length 16 when they expect a matrix. And the Float32Array generally work just like regular arrays (where each element is a number). Matrices are stored in column major order – which is a little weird. See my other tutorial for an explanation. GlMatrix has the same issue, and explains it on its webpage.

Similarly, points and vectors in twgl.m4 are arrays of length 3. It will always make Float32Array, but you can use any array of length 3 as input to its functions.

To help me experiment with twgl.m4, I wrote something simple that prints out points and matrices so I can try things out. You can look at it here. (link to jsbin, I am not embedding it).

One of the things you’ll notice is that twgl doesn’t have 4 vectors – just 3 vectors. It treats 3 vectors as 4 vectors as 4 vectors with the last component being 1. Most of the time it’s OK. If you have a transformation that does something to the W component (like a projection), when you use the m4.transformPoint function, it will do the divide by w for you. Beware.

Using TWGL.M4 with HTML5 Canvas

Most of the time, the HTML5 Canvas matrix stack is just fine. But, if you want to use twgl with it (for example, to practice using twgl before we get to WebGL, or a class assignment). The only trick is that you need to apply the transforms you have to each point yourself.

Here is a simple example – a triangle (what’s simpler? I guess I could have just made a line) spinning. Done with both regular canvas and with twgl. Rather than discussing it, I just put lots of comments in the code to help you understand. Again, the link is to JSBin – no embedding.

You probably want to understand this program.

]]>
Matrices and GL https://pages.graphics.cs.wisc.edu/559-Old-Tutorials/matrices-and-gl/ Mon, 07 Sep 2015 01:44:49 +0000 http://pages.graphics.cs.wisc.edu/559-Old-Tutorials/?p=74

There is some weirdness and confusion in notation for transformations, which becomes real confusion when you actually need to implement it using someone else’s libraries and code.

Short verson:

  • In class, we will use right-handed coordinate systems and the post-multiply convention.
  • In GL (whether its old-fashioned GL, OpenGL, WebGL, …) matrices are stored in column-major form. You can think of this as still being post-multiply, just that all the matrices are transposed (so when you do the multiplications, you actually multiply on the left).
  • In GL, the coordinate system can be either right handed or left handed. The only place where the Z axis direction (into or out of the screen) matters is for the Z-test – and you can pick which function you want for the z-test.

You can see a discussion at the glmatrix web page as well.

Long version:

When we compose transforms, it’s nice to think of it functionally:
non-local coords = transform(local coords)

So we get
final coords = transform( transform( … (transform (local coords))))

If our transforms are linear operators (matrices), this ends up looking like:

    \[ \mathbf{x'} = \mathbf{D\ C\ B\ A\ x} \]

where x is a point in local coordinates,A,B,C and D are transforms (matrices, and x’ is the point in global coords

This is called the post-multiply convention.

If you think about it, this is writing backwards. First apply transform A to the object. Then apply transform B to that. Then apply C. So, some people like to write it:

    \[ \mathbf{y\ P\ Q\ R\ S\ = y'} \]

In this case, y is transpose(x), P is transpose(A), etc.

This is called the premultiply convention.

Aside: be careful that this is re-ordering, not inversion. It is one thing to say:

    \[ \mathbf{x' = M\ x}   \Longleftrightarrow  \mathbf{x^T\ M^T = x'^T} \]

it’s quite another to say

    \[ \mathbf{x' = M\ x}   \Longleftrightarrow  \mathbf{x = M^{-1}\ x'} \]

transpose is not inversion.

Notice that this is just notation that you might not need. If your program doesn’t look inside the matrices, you can happily speak in terms of transformations (assuming that each transformation operator applies to the local coordinates of the objects inside)

translate(...)
rotate(...)
translate(...)
rotate(...)
scale(...)
draw object

Except that sometimes your program actually has to look inside of those matrices. Especially since with WebGL it doesn’t compute them for you.

So now you might ask… is WebGL pre-multiply or post-multiply? And the sad news is you won’t find a consistent straight answer.

Here’s a way to think about it: WebGL does follow the post-multiply convention. However, it stores all matrices transposed. Therefore, you either need to transpose the matrices before sending them to GL (in old-fashioned GL you used the “loadMatrixTranspose” and “multMatrixTranspose” functions rather than “loadMatrix” and “multMatrix.” Usually, you’d use the commands that created the transformations (translate, rotate), so this wasn’t a big issue.

Now, with “modern” GL, you have to implement matrix stuff yourself. Even if you get a library that implements matrix multiply, you still have to make your own stack.

This doesn’t seem to bad. I want to do

    \[ \mathbf{D\ C\ B\ A\ x} \]

I define “multmatrix(M)” to be stackTop = stackTop * M
multMatrix(D)
multMatrix(C)
multMatrix(B)
multMatrix(A)
use matrix for drawing the points

And I just need to remember to transpose the matrix before i sent it to GL (in that last line).

Except… if I am using a library, that library might be designed to keep all of the matrices transposed. So if I say “give me a translation matrix” it will actually give me the TRANSPOSE of the rotation matrix – since it knows that eventually you will want to send it to GL.

We could transpose these matrices into the form we like, multiply the way we think about stuff, and transpose them back.
multMatrix(transpose(get D from library))
multMatrix(transpose(get C from library))
multMatrix(transpose(get B from library))
multMatrix(transpose(get A from library))
use transpose of matrix stack top to draw the points

But that’s a lot of transposing. Instead, we remember that:

    \[ \mathbf{B\ A} = \mathbf{(A^T\ B^T)^T} \]

So we can just keep all the matrices transposed all the time, but just switch left-multiply to right multiply.

So, hopefully, you are wondering “why does OpenGL store the transpose of the matrices?” Which is a good question. This isn’t a mean trick from the developers, it’s a historical artifact.

In modern programming languages (C, JavaScript, Python, …), the convention is to store matrices in row major order. That is is you turn your 2D array (matrix) into a 1D array (list):

1 2 3
4 5 6     1 2 3 4 5 6 7 8 9
7 8 9

In some other programming languages, popular at the time GL was invented, matrices were stored in column major order:

1 2 3
4 5 6     1 4 7 2 5 8 3 6 9
7 8 9

So, in the minds of the designers of GL, they are storing the matrices the right way: non-transposed, but in column-major order. They also thought about things using the pre-multiply convention.

For me, using modern languages, I think of GL as using the matrices transposed, and working with my post-multiply convention. I just need to remember that I need to left multiply rather than right multiply.

I’ve been working with GL variants (beginning with the original IrisGL, and now up to WebGL) since 1989. This has bugged me since day 1. And I still forget it and have to check from time to time.

]]>
When do I draw? (some comments on code organization) https://pages.graphics.cs.wisc.edu/559-Old-Tutorials/when-do-i-draw-some-comments-on-code-organization/ Sat, 29 Aug 2015 03:15:43 +0000 http://pages.graphics.cs.wisc.edu/559-Old-Tutorials/?p=47

Warning: this is from 2015. Some of it is obsolete – there are newer (and better) ways to do things as JavaScript has evolved.

One thing which is weird about JavaScript (in the web browser at least) is that your program doesn’t have a beginning. It is embedded on a web page, and attached to things. This brings up questions of when your code actually gets run. It is particularly important for drawing – since you want to draw at the right time.

This is a bit of web programming detail – it is more about how web browsers work than graphics or JavaScript. You need to worry about this so your web programs work.

Draw on Start

There’s a problem that when you write some JavaScript code on a web page, there’s an issue of when it actually runs. Consider the most trivial example.

JS Bin on jsbin.com

You would think that the script should run after the canvas gets created. And most of the time it does. But since web browsers are smart, they might not finish step 1 before step 2. So the canvas might not be set up before the script gets run. Or worse, you might not want to put the script in the middle of the body – you might want to load it at the top of the program (especially if you are loading it from another file).

Here’s something that plain does not work: just sticking the code into the top part of your html page (the <HEAD></HEAD> block – which I call the header, although that might technically be a misnomer). It’s not unreasonable to want to put it there – especially if you are loading the script from a file, you might want to have the browser start fetching that file before it needs it. However, if the code runs at the beginning of the web page, it almost certainly will run before the canvas gets created, and will fail.

As with most things web, there are lots of different ways to deal with this “when do I run my script” issue. The one that I use is to have the code execute when the window is finished loading. To do this, I set the window’s “onload” function to be the code I want to execute.

JS Bin on jsbin.com

As you can see, this isn’t too much different than the first example. The big difference is that I’ve put my drawing code in the header of the HTML file. However, rather than running it, I instead define a function with the code inside and assign this to the window’s “onload” attribute. This way, they code gets run when the window is done loading, so that I know that all the HTML objects (like the canvas) have been created.

If you’re a web pro, you probably would have reasons to prefer an even fancier method. But this usually involves learning about some other library (jQuery’s “ready” function seems to be the preferred approach). For this class, onload functions are probably good enough.

I had the code execute with the window’s onload. Some people put it on the body’s onload. I am not sure if it makes a difference. It might make a difference if you put stuff after the body (but still on the web page).

Draw on Update

Here I’m going to do something simple: I want to make a slider (on the web page) and have the X position of the square be determined by the value of the slider. Making a simple slider is easy: there is a “range” object that we can put on the web page. Then, in our script, we can find the slider (just like we found the canvas), and ask it for what it’s value is.

JS Bin on jsbin.com

One trick: we can’t draw the rectangle until after the slider has been made (since we need to ask the slider where we’re supposed to draw). Our “onload” trick from above can help with this.

There’s another trick: when the slider changes, we need to redraw the picture. Remember, we’re using an immediate mode API. When we draw the square, we are actually drawing the picture. If we want the square in a different place, we need to redraw the picture (for now, the whole picture – there are ways around that, but it’s a longer story).

JS Bin on jsbin.com

So what I’ll do is to make the thing that draws my picture into a function (I’ve called it “draw”). I’ll call it during the onload function. But I’ll also want to call the very same draw function each time the slider is moved. Notice the line where I “attach” the draw function to the slider, so it gets called when the slider gets moved.

http://www.impressivewebs.com/onchange-vs-oninput-for-range-sliders/

Some comments on JavaScript Style and Efficiency

Let’s think about this code for a minute – and see how some of JavaScript’s features are leading us into potential problems as this program grows more complicated…

First, notice that draw is a global variable. We can only define one draw function. If we load another module, and it wants to use the name draw, it will over-write this one. For the draw function, this might not be such a big deal – but we probably want to avoid having too many global variables.

Second, notice that on every update, we have to search the whole document for the canvas and the slider. If the document was big, this could be time consuming: and we want draw to be fast, since we want the screen to update as we move the mouse. An obvious thing to do would be to find the canvas and slider once, store them in a global variable. Of course, this makes a yucky global variable. There is also the problem that this has to happen within the onload function (because we can find them until we’re sure the page is ready).

There is a nice way to address both of these problems, using the basic features of JavaScript (the fact that it is a lexically scoped language that supports closures). This is a common paradigm of JavaScript programming that you will see a lot: use scope and closures to build other useful abstractions and achieve things (like modularity) we like.

The idea is that we put everything into the function that gets called onload. Note that in this example, I am also giving that function a name – but we could have created it anonymously as in the previous example. The more important thing to note is how all the things we might have declared as global, are instead placed inside this function – so they can only be seen inside this function.

JS Bin on jsbin.com

Notice how this solves both of the issues above. The draw function is now not global – nothing outside of the setup function can see it. Similarly, I can create other variables (canvas, slider) that are similarly hidden. Since they are inside the setup function (which only gets run at “onload”) they happen at the right time and place. And that I only search for them once when the page loads – not each time the slider moves.

Take time to understand this example – it gives you a sense of a real JavaScript programming idiom. It shows why programming in JavaScript might be different than some other language you’re used to.

Draw All the Time

Suppose I want to just keep redrawing. This doesn’t make sense if the picture isn’t changing, but if the picture is animating (changing on each frame) then I want to keep redrawing. As soon as I finish drawing, I want to draw again (or maybe wait a little while). The trick is that we want to give the web browser a chance to do other stuff too.

JS Bin on jsbin.com

Again, there are probably many ways to do this. The one I learned uses a feature called “requestAnimationFrame.” The idea is that this schedules a redraw at some time in the future. It’s a method of window.

Notice that I commented out the extra call to “draw” when the slider changes. Because the things are being redrawn all the time, we don’t need to force a redraw when the slider changes. In fact, if we ask for an extra draw when the slider changes, this will add another request for a redraw, and before we know it, we’ll have way to many requests, and things will go crazy.

http://creativejs.com/resources/requestanimationframe/
https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame

One problem with requestAnimationFrame is that it tries to go fast (60 frames per second). So a different possibility is to schedule the redraw a certain time in the future (some number of milliseconds) use “setTimeout”. You can look up how to do that. You can also look up debates as to why one is better than the other.

What you should have learned

This isn’t really graphics, but its stuff that is useful for writing graphics programs. Hopefully, you got a sense of when you can make drawing happen in your web-based graphics program: this will also be useful when we start using other APIs than Canvas. You saw simple ways to:

  1. Make sure your pictures get drawn onto a web page
  2. Add a slider to your program so you can change things about your picture
  3. Make animation
  4. Use common JavaScript programming idioms to organize your code.

Now you can use this to make something less boring!

]]>
What is a Pixel? (and what is a point sample) https://pages.graphics.cs.wisc.edu/559-Old-Tutorials/what-is-a-pixel-and-what-is-a-point-sample/ Fri, 28 Aug 2015 19:14:23 +0000 http://pages.graphics.cs.wisc.edu/559-Old-Tutorials/?p=37

An updated version of this tutorial is available on the 2021 Course Web

When we talk about image-based graphics, we talk about it being a regular collection (usually a grid) of samples (or pixels). It’s time to be a little more precise about this.

The term pixel is (I’m told) short for the term “picture element.” (Wikipedia, of course talks about this)

Unfortunately, there is an ambiguity when we talk about a grid. And for reasons that we become clearer later, it is better to think about pixels one way rather than the other. Consider a grid:

There are two different things we could refer to as “the elements:” the squares bounded by the lines, or the points at the corner of the square. Note that both of these objects (the squares and the corners) are regular rectangular grids.

It turns out that it is best not to thing about the region inside the square. It is better to think about things as point-samples.  That is a measurement taken at a specific position (where “position” is a mathematical idealization of having no area). It will be much better to think about a pixel as a point-sample.

You might notice that when we take the grid (as in the picture above), there are more corners than there are squares (there is one more row/column). We usually prefer to consider the point sample as being the center of the square. Or, since we use the sample positions much more than we consider squares that are centered on (and surround) the point-samples.

In an image, we make a measurement (usually color or brightness) at each point-sample location. When we say a point sample has a particular color, we are only talking about that specific point in space. Two questions probably come to mind:

  1. What about the spaces in between the samples?
  2. Wouldn’t we have avoided that problem if we instead assigned the color to the area inside the little square?

The answer to #1 is “we really don’t know what happens in between the samples.” A sampled representation only tells us about what happens at the samples. If we’re trying to guess about other places (e.g. to fill in the gaps to make a continuous image), we’re doing just that: trying to extend beyond what we were told. This process of trying to figure out reasonable values for other locations is called reconstruction.

You might think that the problem is that we’ve assigned the color to a point. But, the alternative (assigning the color to an areal region, such as the little square) not only doesn’t help, but creates new problems.

Suppose we did consider that each color is assigned to a little square. It still leaves the problem of deciding what color occurs are the edges and corners where the squares come together. But it also makes the assumption that our picture is made up of squares of constant colors. In the real world, very little is exactly this. Your computer monitor (LCD / Projector) or printer is more like a bunch of dots that blur together. The objects that you’re making pictures of are unlikely to have been made from little squares (unless it’s a tile floor or something like that).

The real problem is that we’re trying to represent something that is continuous (that has a value at every position) using a finite set of measurements. The thing we want to represent (a picture, an image) might be arbitrarily complex. But in an image, we are only storing a fixed size set of measurements. Some information will be lost. Using the point sample model, we are aware of what we’ve lost, and can talk about the best ways to measure that loss, and to reconstruct as well as possible.

If we view each measurement as a point sample, we can choose how we do reconstruction to “fill in the spaces between.” Making little squares is one kind of reconstruction (sometimes called “nearest neighbor” reconstruction because every position is assigned the value of the sample closest to it). Later in the course, we’ll learn about many different kinds of reconstructions.

Of course, considering things as point samples extends more gracefully to cases where we aren’t using a rectangular grid. But more importantly, the mathematics will be far simpler and more elegant.

We’ll explore all this in more detail later when we talk about signal and image processing. But for now, please remember:

A pixel is a point sample.

An image (in the sense of image-based graphics) is a regular grid of point samples,

A pixel is not a little square.

For Further Reading

Wikipedia article on Pixel says where the word comes from and also gets at the point-sample issue.

Alvy Ray Smith’s article “A Pixel is Not A Little Square” 

Terms you should know

Pixel

Point-Sample

Reconstruction

]]>
Image-based graphics vs. Object-based graphics https://pages.graphics.cs.wisc.edu/559-Old-Tutorials/image-based-graphics-vs-object-based-graphics/ Fri, 28 Aug 2015 19:11:23 +0000 http://pages.graphics.cs.wisc.edu/559-Old-Tutorials/?p=35

There’s a very basic distinction in kinds of pictures (and therefore kinds of graphics) we use with computers. The difference is really simple, but very difficult to describe precisely. In fact, we don’t even have great words for the two categories.

In the old days, they referred to the two types as “raster” and “vector”. I prefer “image-based” and “object-based”.

Here’s a first attempt at the definitions:

  • An image-based (or raster) graphic represents the pictures by measuring the color at a pre-determined set of locations (usually a grid). Think of a picture taken with a camera: it tells you a color for each point taken on a fixed grid.
  • An object-based (or vector) graphic represents the picture by describing the objects in the picture in a mathematical way. For example, I might list the 2D things (lines, circles). The number and positions of these objects can vary.

One of the reasons this gets a little tricky is that we don’t actually look at an object-based graphic. Our display devices are pretty much all image-based. LCD screens, laser and ink-jet printers, CRT monitors, computer projectors – all show raster images (regular grids of color measurements). So, if I try to show you an object-based graphic, it would be converted to an image-based graphic so that it could be displayed. The process of converting an object-based representation to an image-based one is called rendering.

The simplest form of image-based graphic is a grid of pixel values, where each pixel is a color or brightness. Each one is a measurement of what we see at a particular place. Those places are fixed. If we have a different picture (of the same size), we change the colors at those positions. For example, every picture that my digital camera takes has the same regular grid of pixels (for my current camera, it’s a 4592×3056 grid if you care). At each position on that grid a picture has a color. Whether I take a picture of a white wall, or some  complex street scene or landscape, it’s always the same grid – it’s just that the patterns of colors are more or less complex.

 
 
 

sign on trail grey ski slope notwhite-vsmall

Three pictures taken with my digital camera (greatly reduced in size). Each has the same 150×100 grid of pixels, even thought the images are quite different. In an image-based graphic, the places where colors are measured are fixed, while the colors at these positions are different.

 

A simple form of object-based graphic is a 2D vector graphics image, where the picture is represented by a list of 2D objects like lines and circles. These simple pieces are called primitives. An object-based picture might be a list of these primitives. Note that each primitive can be varied in position, and more can be added to make a more complex picture.

   

Three “vector-graphics” pictures. The first two have two lines, albeit in different places and with different colors. The last one is just a grey rectangle. It (should) look the same as the right-most picture above (of the image-based examples).

Note that your web browser has rendered the vector graphics to images to show on your screen.

Object-based graphics are even more common in 3D, where we describe “scenes” as collections of 3D objects. We will typically do this by breaking the scene up into small objects (called primitives).

Let’s contrast those rightmost pictures in each of the boxes. They both appear as grey rectangles. (the photograph might have a spiffy black border around because the website puts borders around images, and it doesn’t consider vector graphics images). The difference is in the representation. The image describes the color at every pixel on a regular grid. Since the picture is 150 pixels wide and 100 tall, this means the picture is a list of 15,000 colors (one for each pixel). They just all happen to be gray. The vector picture representation just says “gray rectangle” (with some other information that says where the rectangle goes).

For a simple picture (like a gray rectangle), an object representation is more convenient since its easier to specify and easier to change.  For a complex picture (like a mountain scene), an image representation is more convenient since it would be really hard to make the exact mountain you see out of simple primitives (whereas, you can make the picture easily with a camera).

In a Graphics Class

Traditionally, computer graphics classes have focused on object-based graphics. It’s often what you think about as “graphics”: making pictures out of complicated 3D objects and then rendering them into 2D images. Images typically were discussed in a different class (like “Image Processing” – nowadays we might call it “Computational Photography”).

However, understanding images is really important for a number of reasons.

  • If you make an object-based representation, you will ultimately need to make an image if you want to see it. So, understanding images will come up (unless you let someone else take care of the rendering for you, which actually isn’t such a bad idea). Note that there are plenty of reasons why you might make an object-based representation of a 3D object besides making a picture of it.
  • Images are increasingly common in computer graphics. With the advent of the digital camera, image-based graphics are everywhere. If you look on your cell phone, most web-pages, in the movies, on pages of a book or magazine, etc. you will see examples of image-based graphics (even if you don’t know know it – most pictures these days, in print, television, and movies, etc. are digital).
  • In fact, you don’t see object-based graphics except in specialized cases. Text (like this web-page) is an important special case. But how often do you actually encounter 3D graphics in your regular life? (other than say, in a computer game, or as a special effect in a movie)
  • Even then, images are a critical part of object-based graphics. Often we describe objects by talking about the images that define their appearance (we’ll discuss this as “texture-mapping” later in the class). And of course, we’ll need to consider how those object-based graphics are ultimately going to be rendered to images.

So, (in this class at least) expect to learn about both object and image based graphics.

What’s so hard about this?

For image-based graphics, it’s easy enough to say “an image is a grid of pixels.” Except that it doesn’t have to be a grid, and I haven’t explained what a pixel is (soon I will).  We’ll explain pixels sometime in the future. If you don’t want to be really precise, and only care about the common cases (or the cases you’re likely to encounter), the distinction really is simple.

The thing that really defines “images” in the sense we’re talking about is that the are sampled representations (we’ll explain what this means at some point – for now, you can think of “we make a measurement at a specific point”) where those samples are taken at specific locations.

Usually in 2D, when we make images, we sample in a (rectangular) grid. A square pattern. it doesn’t have to be that way. We are unlikely to encounter another sampling pattern in class.

From the other perspective, we haven’t really defined object-based graphics very well either. A graphic is a collection of primitives (which we haven’t been too specific about). Of course, our definition has to make it such that a sample isn’t a primitive, otherwise an image-based graphic would be an object-based graphic.

2D and 3D

You can have 3D images – it’s just that the sample positions are in 3D space. You can sample in a grid pattern, or some other pattern.

In this class, we will usually only talk about 2D images. Most of the stuff we do in 3D will be object-based, and we’ll talk about the process of rendering those 3D object representations into 2D images.

3D (and higher) images do exist. In fact, image-based 3D is especially important for medical applications (called volumes) and other places where you are trying to understand what happens “inside” of a solid object. We’ll come back to talking about these volumes at the end of the class (if time permits).

Computer graphics is usually concerned with making pictures of things, so we don’t worry about the insides as much. So typically, when we make 3D things, we only model their outside appearance, and then render them to 2D images. Of course, with the growing importance of 3D medical imaging and 3D fabrication (e.g. 3D printers), learning to model the insides become more important.

Words You Need to Know

  • image-based (or raster) graphics
  • object-based (or vector, or primitive-based) graphics
  • render (rendering) – note that sometimes rendering refers to the more general process of converting from one representation to another, and other times it refers to the specific problem of creating a 2D image from a 3D scene description
  • primitives
]]>
Points, Vectors and Coordinate Systems (why are points and vectors different?) https://pages.graphics.cs.wisc.edu/559-Old-Tutorials/points-vectors-and-coordinate-systems-why-are-points-and-vectors-different/ Fri, 28 Aug 2015 19:09:10 +0000 http://pages.graphics.cs.wisc.edu/559-Old-Tutorials/?p=33

See the updated version on the Spring 2021 CS559 Course Page

It always bugged me that math books made a big deal of the difference between points and vectors. They’re both just a list of numbers, right?

In practice, yes, they are both lists of numbers. But getting an idea of what the difference is helps develop the intuition of coordinate system.

To describe this, let me use an analogy/example: describing walking in a room. Assume that you know which way is north.

  • a vector is a movement that you can make. like “2 steps north, 3 steps east”
  • a point is a position. it’s a place in the room. like “the south east corner” or “the center”

Notice that a vector doesn’t say where you start or end. Just how you should move.

Notice that it makes sense to do arithmetic on vectors. For example you can double the vector (if you do the movement described twice), you can add two vectors (do the first movement, then the second movement – combined into one movement). It makes less sense to do this with points (twice the center of the room?)

Some operations mix the two. You can take a point and add a vector (start in the center of the room, go 2 steps north and 3 steps east). You can take two points and talk about the vector between them (how do you need to talk to get between the points).

Vectors as Points (and points as vectors)

We can add a vector to a point to get another point. This gives us a way to describe points. We need to have a starting point (the origin). And then we can describe other points by the vectors that take you from this origin.

So, a point is just a vector with a known origin.

Think about it this way: if we agree that the south east corner of the room is the origin, then 5 steps north, 6 steps east is the “middle of the room” (for the room I’m in now). Or in Madison, the capitol is the center of the coordinate system, so the computer science department is “12 blocks west” (hence the number 1210).

Coordinate Systems

Having an origin is only part of what we need to interpret a point (or vector). Notice in the descriptions we use the terms “steps north” and “steps east”.

To interpret a vector, we basically need other vectors that will tell us how to interpret each of the numbers. “One step north” and “one step east” are the building blocks from which we build more vectors. These are actually vectors themselves. So, yes, we define vectors in terms of other vectors – the story of the world being carried on the back of a turtle, who is on the back of another turtle, and its turtles all the way down comes to mind (if you don’t know this, don’t worry about it – but I just learned from Wikipedia that its not actually a Hindu myth).

So, to describe what a vector means (in 2 dimensions), we need 2 basis vectors that tell us how to interpret  the two numbers.

If you want to define a coordinate system (something that tell us how to interpret a point) in two dimensions, we need two basis vectors and an origin. If you have these things, then you can take pairs of numbers (2-vectors, or coordinates) and interpret them as points/positions or vectors.

So, if we agree that the origin is the south-west corner of the room, and our basis vectors are a step north and a step east, you can interpret (3,5) as a position: it’s the place you get to if you start at the origin and take 3 steps north and 5 steps west.

Or, to give a more practical example…

If we agree that the origin is the top left corner of the page/screen, that the first basis vector is one pixel down, and the second basis vector is one pixel to the right, then pairs of numbers like (40,75) tell us positions on the page/screen.

Getting to know your bases

If that seems like a roundabout way to get to how we define positions on the screen, you’re right. However, understanding these concepts is really important because it will help us generalize to other bases and coordinate systems.

A quick idea of where this is going…

You could imagine that there are lots of possible bases. Above, I gave one for the screen, but I could have equally picked another one (say, the origin is the center, and the first basis vector is from the center to the right edge, and the second basis vector is from the center to the top edge). If we’re going to talk about positions, we’ll need to know what basis we’re in. We’ll want to be able to use whatever basis is useful, and transition between them. And this is the basis (pardon the pun) of linear algebra.

Notice how we took a geometric problem (describing places and movements) and translated it into a math problem (multiplying and adding lists of numbers).

Next we’ll need to think about bases and spaces a bunch more. But I’ll put that on a separate page.

Read About It In A Book

See Chapters 1 and 2 of “Practical Linear Algebra” (available as part of the online reader).

Terms you need to know

  • point
  • vector
  • origin
  • basis vector
  • basis
]]>
Color: Initial Answers to a Practical Question https://pages.graphics.cs.wisc.edu/559-Old-Tutorials/color-initial-answers-to-a-practical-question/ Fri, 28 Aug 2015 03:05:09 +0000 http://pages.graphics.cs.wisc.edu/559-Old-Tutorials/?p=25

Color

Color is complicated. We will probably spend a week of class on it – and just scratch the surface of its complexity.

But, between now and then you need to make pictures and you will want to specify what colors are in them. So here’s a short version…

Can I really represent Color as 3 Numbers?

In terms of the physics of light: you cannot.

In terms of the perceptual science (psychology): in theory, 3 numbers are sufficient to capture what most people can see.

In terms of computer graphics: 3 numbers are often good enough. But you need to understand the limits and issues in doing so.

In terms of this class: we’ll use 3 numbers to represent colors. Except when we are specifically studying how color works.

Why R, G, and B?

In graphics, we very often will represent a color as three numbers: the amount of red light, the amount of blue light, and the amount of green light. These three colors are the additive primaries: if you add lights of these colors together, you get lots of these colors. This is very different than the subtractive primaries (how different inks mix on paper to block out colors of light), or paint primaries (the colors of paints you mix together to make different colors).

The reasons for RGB actually have to do with the anatomy of the human eye, and the practical issues of building devices that work given the constraints of how the eye works. If we were making computer graphics (and display devices) for ducks or monkeys, we would need to have different primaries.

Most of the time in this class, we’ll use RGB (3 numbers) to represent colors, since it’s good enough most of the time – if only because it’s what our display devices use. When we talk about color, we’ll see why this is (and isn’t) a good choice, see some alternatives, and see some of the ways we deal with the problems of RGB.

Why 0 to 255 for each of RGB?

Really, for each of the color channels (R,G,B) we have a percentage of the maximum brightness. So, in you could use a floating point number (either between 0 and 1 or 0 and 100). In fact, this is probably a better idea than 0-255, and is most likely what is going on inside the graphics card.

Back in the old days, memory was expensive, and floating point computations took a long time. So we really liked to use single byte numbers for storing colors. The 0-255 was a binary fraction (divide by 255). Be careful that it really is divide by 255 (not 256) – otherwise you don’t get 100% brightness.

From the human perception side, it turns out that 8 bits of precision is about the right amount (if you use it correctly). When we study color, we’ll see why between 8-9 bits is all you need in terms of what people see. But we’ll also see why you probably want more precision for doing the computations (which is OK, because now computers can do floating point really fast).

What’s up with the 6 digit hex colors?

For web things (HTML, SVG, …) the common way to write a color is as a 6-digit hex string. 2 hex digits give you 0-255. So 6 hex digits give you a very compact way to write the three binary fractions to make an RGB color. Remember that the denominator is FF (255).

The web formats require that you put a hash mark “#” at the beginning of a hex string to denote that it is a hex string color.

So, “#FF0000” means the RGB triple (255,0,0), which means red.

There is a cheating thing where you give just a 3 digit hex number. In this case, its the same as repeating each digit. “#F00” is the same as “#FF0000” which we just explained.

]]>
Getting Started with HTML5 Canvas https://pages.graphics.cs.wisc.edu/559-Old-Tutorials/getting-started-with-html5-canvas/ Fri, 28 Aug 2015 02:02:21 +0000 http://pages.graphics.cs.wisc.edu/559-Old-Tutorials/?p=14

Why do I need to write my own Canvas tutorial for CS559?

There are some good tutorials out there (I have a few on a list, but that’s just a start). I recommend that you use them AFTER this one. Before you read this one, you might want to read my post on what Canvas is and why we use it.

The problem with those other tutorials is that they all assume that you know a certain set of stuff from prior tutorials. You should be able to figure this out yourself, but in case you need to be walked through it…

You should start with the explanation of what I mean by Canvas

Then we can start…

To draw, you need to answer three questions:

  1. Where do I draw?
  2. When do I draw?
  3. What do I draw?

But since you can’t do any without the other, we’ll look at them all together.

The simplest possible program

JS Bin on jsbin.com

Notice that this is an HTML file – you can load it into your web browser. I am using a spiffy thing to embed it on this web page so you can see the code and the output side by side. You can edit the code and see what the changes do. You might want to move the divider between the code and the output so the lines don’t wrap.

You should recognize some of the basic HTML stuff. This page is really minimal – it has no “<HEAD>" section (which is where I would set the title and other useful stuff). This is bad, since some of the stuff in the HEAD is important (like declaring the character set). In practice, you might not want to make your pages so minimal. I wanted to keep it simple here (so it fits on the screen). Later, I’ll show you a more realistic example.

In the body, you’ll see there are two tags.

The first is the canvas tag. This creates a blank rectangular space on the web page. The size is set by the width and height. I have given it a name (or "id") of "myCanvas" – this is important, since I will need to refer to it later.

The second thing in the body is a "script" tag – inside this script tag, I put my javascript code. Technically, I probably should have had the script tag say javascript – but the web browser will figure it out.

The script is simple. It finds the canvas (that I made above) by looking up its name. It then gets the drawing context from this canvas. The drawing context is the object that we use to actually do the drawing – it stores all the information about drawing state.

Aside… I could have done this differently. Rather than naming the canvas and searching for it, I could have searched for the first (or last) canvas on the web page – but this is bad practice, since it makes assumptions about the rest of the web page. In fact, I could have just assumed there wasn’t a canvas and added one to the end (or beginning) of the web page right in the JavaScript code. This is less desirable because it makes it hard to mix the canvas with other stuff on the page.

Aside… This code works and is simple, but in practice is way too simple. For example, there is no error checking. When writing a JavaScript program you need to worry about errors. Also sticking the program right in the html becomes unwieldy when the program is more than a few lines long.

Then, finally, I can actually do some drawing. Notice that I need to start a path before I can do anything. Then I add a rectangle to the path. Then I fill inside the path.

Besides the fact that the picture I drew is really boring (a black square), there are some over-simplifications in this example that you should understand before trying to draw more.

Where do I draw?

There are two parts to the where question.

The first part of the question is the space we’ll actually be drawing on. This is a canvas element on a web page. To be able to create this, you’ll need to know enough about web pages to make one that you can put a space on, and then actually put the canvas tag someplace.

Web pages usually give a lot more information about themselves, so that the browser doesn’t have to guess. It’s probably a good idea to do some of that.

You can put other web-page stuff around the canvas element – this is useful for making titles, or putting controls (like sliders), or even documentation.

Once you start drawing, you’ll need to understand the coordinate system of the canvas (so when you position things, you’ll know where things will go). For canvas, this is simple: by default, things are measured in pixels, the origin in the upper left corner, and the positive Y axis goes down.

When do I draw?

Or… where do I put my code?

If you notice, I placed my program code right in the web page within a script tag. This is OK for a tiny program like this, but you can imagine that quite quickly you’ll want to put stuff elsewhere to keep your code organized as it grows bigger.

There is another issue as to when this code actually gets executed. It would be nice to assume that everything works all linearly. The script tag gets processed after the canvas tag is done being processed, so the code inside the script tag only gets run once the canvas has been created and is ready to go. In practice, web browsers are more complicated than that. Especially since something can modify the canvas later on (for example, to relocate it to a different place on the page, or put a border around it). So, in a real program, you want to do something smarter about having your code run only when things are really ready.

I’ve written a separate tutorial about this. I recommend that you read it. Either right now, or after you finish this tutorial.

The real answer can be complicated, because it gets to questions of how to best organize your program.

But here’s a more realistic version of that same minimal program

HTML Test on jsbin.com

Here, I’ve turned off the output pane (you can turn it back on to see that the program draws the same back rectangle).

If you read the “When do I Draw” tutorial, this should make sense to you (since it’s one of the examples). If not, what’s happening is I am putting my code inside of a function that gets called when the window is done loading. But the important thing is that the drawing commands (begin path, …) happen at an appropriate time. This is a more realistic program for you to start with. I suggest that you take this and start tinkering with the stuff that actually does the drawing…

What do I Draw?

Now the fun part… we can draw stuff. Preferably something more fun than a black rectangle.

OK, here’s something that’s just a little bit better.

HTML Test on jsbin.com

Notice that drawing has a few parts (that I do over and over)…

  1. I start a path.
  2. I add shapes to the path, either as a whole shape (the rectangle) or by moving a “pen” around (the MoveTo and LineTo that draws the triangle). If the shape is closed, I make sure to close it.
  3. I decide how I want that shape to appear. You can see I set the fill color, the stroke color, and the width of the stroke. I could set other things (like making the lines dashed, or patterns to fill the shapes).
  4. Then I draw it (using the currently set style parameters). I can either fill it, or stroke it.

You’ll notice that I refer to colors in a funny way – as a string beginning with a # (hash mark) and a hexidecimal number following it. This is explained in another tutorial on color.

There are a bunch of different basic shapes (primitives) you can draw. Look at another tutorial to get a more complete list. There are a bunch of different style things you can do. Again, look at some other tutorial. But at this point, you can probably have enough of the basics so that you can start drawing stuff.

If you haven’t done it already, now might be a good time to go back to the “when do I draw” tutorial, so you can get some ideas on JavaScript code organization idioms.

There is a resource list for more Canvas info as part of the “Canvas: What and Why” tutorial.

]]>
HTML5 Canvas: What and Why https://pages.graphics.cs.wisc.edu/559-Old-Tutorials/html5-canvas-what-and-why/ Fri, 28 Aug 2015 01:52:24 +0000 http://pages.graphics.cs.wisc.edu/559-Old-Tutorials/?p=12

This is more of a “Why are we using HTML5 Canvas in 559” than anything else. But to answer that question, I need to make sure you know what “it” is first. This is meant to come before my “getting started” tutorial (since you should know what you’re starting and why you’re starting it).

What is Canvas

Technically, when I say Canvas, I should be saying the “Canvas 2D drawing API” because just “Canvas” could also be referring to the generic container that also serves to provide a space for other APIs to draw on the web page. To save typing, when I say “Canvas” I mean the 2D API.

Canvas is part of the specification for web pages. It gives a way to make space on a web page, and a set of operations for drawing on it. However, to do the drawing (as far as I can tell), you need to access the drawing commands from JavaScript. So Canvas is also a JavaScript API. But this is where JavaScript and web browsers become hard to tell apart. Like most JavaScript APIs, a Canvas is an object that has some methods defined. If you run a JavaScript program in a web browser you can ask for one of these things. There might be other ways to get a Canvas, but I don’t know about them.

Why Canvas?

Of the web graphcis APIs, Canvas is probably not the most popular anymore. Real web pros might say its a little dated. You’re probably eager to use things like WebGL and Three and SVG and …

But, there are a few reasons that we’re starting with it first:

  1. It’s an example of an immediate mode API. The other web graphics APIs are not immediate mode. I want you to have the experience of working with an immediate mode API so you understand the difference.
  2. It’s much easier to get started with than anything else. It will let you practice working with web programming with making the graphics easy. Once you’ve got the web programming bit down, then we can move on to things where you can do more graphics.
  3. It has only basic stuff in it. Which means to do fancy stuff, you have to do it yourself. And I am going to ask you to do some of that. (yes, you will implement your own 3D stuff on top of Canvas)

I have used Canvas this way successfully in a prior class (see CS679 2012 where I just told people to use this for a project,  giving them only a little tutorial). Once you get are comfortable (or at least started with) Canvas and web programming, then you can move on to WebGL and other fancier things.

Getting Started

In order to do things with Canvas, you need to tackle the following basic issues (and I recommend them in this order).

  1. You need to know a little about HTML so you can make a web page and put a place to draw on it.
  2. You need to know a little about JavaScript and how it interacts with HTML, so you can try to have your program draw on the page.
  3. You can start using the Canvas API to draw pictures. Some basic questions will inevitably come up. (where do I draw? when do I draw? what do I draw?)
  4. You need to experiment with the tools (like the debugger in the web browser, and maybe the text editor/IDE you’ll choose to work with.
You can also just try diving in – which I recommend. Look at my getting started with Canvas tutorial. Read through it. When you get to the end (with the sample program) read the sample program carefully and make sure you understand it. Tinker with it (you can change it live right on the web page) and see what happens. Save a copy of it to a text file and try editing it. Load it into a web browser and find the debugger and step through it.
Then, go read some more and become a better JavaScript programmer. In later assignments, you’ll have to write (and read) more complicated programs.

Canvas Resources

I have my own getting started with Canvas Programming Tutorial, made especially for CS559 students.

Eloquent JavaScript (one of my favorite JavaScript books) has a nice chapter on it.

A nice tutorial: http://diveintohtml5.info/canvas.html

Another set of tutorials using a set of live code examples: http://www.html5canvastutorials.com/

Official tutorial: https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial
Official docs: https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API

31 tutorials in order – each discussing a different aspect. Be careful, some of the things aren’t as good as they should be, and they often use jQuery (rather than standard JavaScript). http://creativejs.com/2011/08/31-days-of-canvas-tutorials/

A fun exploration of drawing with the mouse. He makes cool looking line styles. The demos run, but the way he sets up handlers (using canvas.onmousedown and things like that) never work for me. http://perfectionkills.com/exploring-canvas-drawing-techniques/

Handy cheat sheet:
http://cheatsheetworld.com/programming/html5-canvas-cheat-sheet/

]]>