Scratchapixel: Computer Graphics Programming from Scratch
scratchapixel.com
scratchapixel.com
Meanwhile a teenager could easily get an intuitive grasp of 3D graphics if you just explained how translation is nothing besides addition, and that to rotate, you just use good old trig functions to generate rotated basis vectors along which to plot your vertices (really easy to show with images and animations too). And that magic perspective, to make things get smaller as they get further from the camera, is just one divide by the depth away... yes, all very basic arithmetic. And no need for magic such as homogeneous coordinates. They're just a convenience for when you do things a certain way.
You don't need to go to college or even high school for 3D rasterization. But most if not all texts pretty much want to assume such a background?
Actually, I'm quite tempted to try write such a tutorial for the 12-year-old me. Too bad I can't travel back in time to see if I'd actually understand it (but I have a strong feeling I could come up with something good enough). Yeah, the lack of approachable material was very frustrating for me back then. In the end I wrote a very primitive renderer (with plenty of trigonometry per vertex) which was way too slow and complicated to be useful. Because I didn't realize how simple the problem actually is.
The reason I know those things now is because I wasn't forced to learn them then. Detail comes after engagement.
You should do it! I agree and think that making 3D approachable is possible, and that most tutorials fail to make it easier than already available materials. I'm not sure it's easy to do, but if you succeed then people will benefit and if it turns out to be hard, you'll have developed a stronger appreciation for the problem and/or the motivation to solve it.
I'm personally fine with using the computer as a "magic box" to do all the calculations, but it's important to have a geomtrical intuition about the operations. This is another short tutorial that does a good job at conveying the geometrical aspects of linear algebra: http://www.cns.nyu.edu/~eero/NOTES/geomLinAlg.pdf
For those interested in learning LA in full detail, you can check out my upcoming book which covers all the essential material and discusses lots of applications, including the homogenous coordinates used in computer graphics: https://minireference.com/static/excerpts/noBSguide2LA_previ...
The eBook version has been ready for a while now, and it gets constantly updated. I can also print you a one-off copy of the current version if you need it sooner.
"Linux 3-D Graphics Programming" [1]
That explains how to build a 3d engine almost from scratch and it does explain 2D math (cross product, etc) and also 3D stuff of course (matrix operations, perspective projection, etc).
It's a bit dense in that it pretty much builds everything from zero, but it's a very nice way to go through everything needed to work with 3D graphics.
You can check the content table in Amazon I think.
The second book "Advanced Linux 3D Graphics" is a bit less interesting for me since it talks a lot about Blender and other software which it doesn't really go with the theme of the first one, but there's still a lot of good info in there.
[1] http://www.amazon.com/Linux-3-D-Graphics-Programming-Norman/...
The book teaches you how to write a 3D software rasterizer from first principles. The first part of the book is nothing but a well written linear algebra primer. The book then assumes you have nothing but a C++ compiler and a pointer to the frame buffer like you might get using SDL.
Unfortunately the book appears to be out of print, and the APIs used are a bit out of date at this point (Win32 and old DirectX used to set up a window w/ a frame buffer ptr).
All the same, I would still highly recommend it to anyone who wants to understand the foundations of 3D math and fixed function rendering pipelines.
But I think the 12-yo-me wouldn't have bought a book and certainly wouldn't have appreciated one that starts with a linear algebra primer (no matter how well written).
Really, what I would've needed back then would've been a relatively short tutorial somewhere online, preferrably one that doesn't require me to start with linear algebra. Just the basic arithmetic I was familiar with back then. Maybe I will indeed have to try write one now some day.
Short enough that it would be easy for people to contribute translations. Indeed, a math heavy book in English would've been totally inappropriate.
Linear algebra was the new and easy part. You don't need matrix inversions, eigenvectors or triangular decompositions or any of the complex Linear Algebra stuff. It's just vector math. And you probably already know arrays. It's merely a notational convenience when you recognize that you're doing the exact same operations on three x,y,z-variables all the time.
When I saw it first as a teenager I was like "hey that's clever, lots less to write!" (when working out formulas on pen and paper, not having to write everything thrice, yay!).
Video and audio quality aren't great, but you might enjoy it.
I think that most tutorials and such have a more practical focus though, with the goal of getting you to practical use of a 3D programming API (or at least skipping to the more-efficient combined transformations that matrices allow). I know that I found enough resources that covered the low-level view of things when I was teaching myself about this stuff, but I had to sift through a lot, and I ended up mostly dropping it.
Recently, I've been looking for info on doing UV mapping in software. That's pretty hard to find practical information on too.
Learned Linear Algebra (matrix calculations and some analytical geometry) + Calculus in eleventh grade, around 1995. I think it was the standard curriculum in all Eastern Europe and the countries from the ex Soviet Union.
http://webglfundamentals.org/webgl/lessons/webgl-2d-matrices...
It expands to 3d in the following article
Any approach that ignores the relevant parts of linear algebra, though, is probably going to collapse under its own weight as things get more complicated--experiencing that collapse may be interesting from a learning perspective, but I suspect it is not needed.
The real problem is that the useful parts of linear algebra--for graphics anyways--may never be seen before college, and even then they may be presented in the abstract form which prevents their utility from being realized.
Really, any 3D primer should just assume no familiarity with the subject, and then teach exactly those bits which are relevant to computer graphics.
When I teach graphics to 3rd-year college undergraduates, I tell them "this is what all that point-and-vector stuff you learnt in high school was really meant for". They've usually forgotten it all, but it comes back to them quickly, and the matrix stuff on top of that isn't very hard, so I can get them up to speed pretty quickly.
Most CS degrees require linear algebra, which talks about vector spaces, gaussian elimination, diagonalization, rank, which is all useless for graphics! Too bad that course is usually relegated to the math department, which doesn't know how fun and useful a small subset of linear algebra is!
I was fortunate in college to have a professor teaching graphics (Ron Goldman) whose training was in differential geometry. So, graphics to him was a beautiful if trivial application of mathematics and linear algebra and he taught it as such.
I will always value his teaching of mass-point stuff as an approach, because it just is so nice in how it ends up.
I understand where you're coming from: translating a point is just 3 additions, so why do a full matrix x point multiply? Scaling is just 3 multiplies, and so on. But if you've got a hardware matrix-point multiplier, all those transformations cost the same, so you're not saving time by devoting special code to each kind of transformation.
Moreover, you don't have to learn full linear algebra: to do graphics, you don't have to know how to invert a matrix, nor solve a system of linear equations, nor diagonalize a matrix. Graphics just needs a tiny subset of linear algebra.
When I teach graphics, I describe points, vectors, lines, circles, matrix-point multiplication, and matrix-matrix multiplication. It takes maybe two lectures, and it provides tools for lots of other parts of the graphics pipeline.
Once you have those tools, you can talk about the viewing transformation (just a special matrix), composite transformations (matrix-matrix multiplication), hierarchical objects (more matrix-matrix multiplication), projection (another special matrix), color transformations (another special matrix).
I also find that when describing ray tracing, you need to talk about going from (row col) pixel coordinates to a 3D point in space, where the ray starts. That's partly the INVERSE view transformation, and (yay) it's just a matrix.
When I was a wee lad in 1981 I did indeed try what you suggest: I worked out the algebra of projection, knowing just where the image plane was (using some points and vectors), and where the world point was. This give me an image point. I was very proud to be able to squeeze this into 50 opcodes on a TI-57 calculator. But when I became a man, and put away childish things, I saw that matrices describe the same process much more cleanly and simply. I wish I had known about them much earlier.
Hell, I wish high school math taught some points and vectors, and some simple matrix operations as I described above (not full-blown linear algebra). Then, they could use those tools to make pictures starting from just numerical descriptions of shapes! It would give many kids more enthusiasm for mathematics, and would start them on the way towards operators, groups, linear spaces, and all those things they might see later. All we would have to do is get education departments to teach the math teachers all this stuff. It would be exhilarating for everyone involved.
Oh, I'm not arguing against the utility of matrices. I just find that they were too abstract a concept for the young me to learn at the same time while trying to understand 3d graphics. They're an useful abstraction for when you know them, but if you don't, focusing on them is a good way to frustrate a young mind who just wants to understand 3d transformation and perspective projection.
Even if you read about matrices and vectors, it takes quite a bit longer to get comfortable with them and build intuition. Instead, with weak knowledge and lack of intuition (can you expect more from a young teen who had to try learn about these things himself on the net in a foreign language?), dressing the simple core of 3d computations in that language only serves as a barrier to understanding, and you have to work hard backwards to really understand what's happening "under the hood", below these abstractions. It's a bit much to comprehend, and I don't think it helps. It didn't help me for sure. And that ended up being incredibly frustrating, crushing even. It could just be that I am dumber than the lot of you?
If anything, it would've been better if someone could've shown how simple and intuitive the underlying arithmetic is, and then from there on go on to show how one can wrap things up with useful abstractions to combine later. This would give the motivation to learn the more abstract material, and straight away show how it is useful, applying it to things you know already. To me, that would make as much sense as learning to do arithmetic before learning about functions and solving equations.
And really, I wasn't that interested in using graphics hardware or some library. For me the point was in doing it all from scratch.
Example: a parametric line segment: P(t) = t * A + (1 - t) * B: If t is 0, you get A. If it's 1 you get B. If it's 0.5, you get halfway between A and B. If negative, you're 'before' A. If t > 1, you're 'beyond' B. Then it's easy to see that restricting t > 0 gives you a ray. The geometry matches the algebra nicely.
Example: in ray tracing, you have to test whether a ray intersects a sphere. This gives you a quadratic equation. If the equation has two real roots, the ray hits the sphere twice. If just one real root, it touches it once (one hit point: ray is tangent to sphere). If no real roots, the ray misses (no hit points). I love how the algebra and the geometry correspond so nicely.
Once you tell a student that applying a matrix will change an object's shape, it's easy to get them to see how applying two matrices means applying two shape changes. Then if you apply the changes in opposite order, you get a different matrix product, and a different final shape. Again, the algebra corresponds to the geometry. And you've just taught them about non-commutative multiplication!
And then I show them a translation matrix, and the inverse of the translation matrix (I don't teach them how to invert matrices; why bother them?). And I show them that the inverse makes sense: the translation amounts are the negatives of the original. And I show them that the product of those two matrices is the identity, which again matches the geometric fact: move, then un-move, is the same as doing nothing.
I talk about rotations using my body: I turn around the X axis, then the Y axis. The I repeat it in opposite order, and show that rotations usually don't commute.
What I'm trying to say is that matrices are confusing because teachers SUCK at explaining them. For the small subset of linear algebra that graphics needs, there are a lot of geometric intuitions that make it simple to explain the material.
It was more like teaching a child to tie a shoelace and then assuming that he can work out how to tie all the different types of knots needed on a sailing ship than it was actually teaching.
https://www.youtube.com/watch?v=GNO_CYUjMK8
Despite the title, the talk is NOT WebGL specific. It's a fantastic, FANTASTIC tour of 3D graphics fundamentals.
This is, IMHO, quite simply the best presentation I've ever seen on how matrix math relates to graphics programming.
Also see Stevens' site: http://acko.net
Side note - There are some great pages there, be sure to check this one out if you're at all interested in how math is applied to animation:
Ray Tracing in a Weekend Series. Most the way through the first book and I plan on continuing it. [1][2][3]
Tiny Renderer - How OpenGL Works. A software renderer in 500 lines of code. Wiki has a full tutorial. [4]
The Book of Shaders. A step by step introduction into fragment shaders. [5]
[1] https://www.amazon.com/_/dp/B01B5AODD8
[2] https://www.amazon.com/_/dp/B01CO7PQ8C
[3] https://www.amazon.com/_/dp/B01DN58P8C
I really wish everyone would move toward something like this instead: http://w3.impa.br/~diego/projects/GanEtAl14/
You say 'games and movies' like those are niche markets. You can't watch any TV without seeing 3d graphics. And chances are you see a lot more 3d on your computer than you think while you work. Windows, Mac OSX, & Linux all have 3d hardware accelerated windowing features for task switching, virtual desktops, and lots of other fun tidbits. Plus, you might not be playing enough games, if you play games less than 1% of your time.
I'm not sure who's over focused on 3d, but it'd be pretty weird to put together a site like scratchapixel.com without 3d.
Finally, Bresenham's algorithm has historical significance, but is no longer generally useful, even for line drawing. Maybe if it's gone from CGP&P, that's a clue? Aliased, single pixel wide lines are almost never used. If you want soft edges or thick lines or curves or texture, you're a lot better off focusing on polygons from the start.
And if you're e.g. filling a triangle? Going the barycentric way, you have a relatively speaking big amount of floating point operations per pixel, in addition to the loop, plus some initial setup. And you might have to compare signs...
I don't believe it's faster. But I'm open to being shown wrong.
Or maybe I'll discover I was using a branch after all!
https://hbfs.wordpress.com/2009/07/28/faster-than-bresenhams...
Both are significantly faster than the naive floating point version.
That is in line with my experience that floating point can still be quite slow on the CPU; the advantage from using fixed point isn't necessarily in avoiding branches (though it usually helps), but in avoiding floating point computation and conversion between floats & ints. Which is something something you have to deal with as soon as you're addressing memory or trying to pack data e.g. in video coding.
If you have a "brancheless bresenham" then go for it, I've never heard of such a thing so I'd be curious to see that link. But from the description it sounds like a contradiction to the Bresenham's idea.
> Evaluating the curve's equation for values of tt going from 0 to 1, is sort of the same as walking along the curve. It is important to understand that tt is a scalar but that the result of the equation for any tt contained in the range [0:1] is a position in 3D space (for 3D curves, and obviously a 2D point for 2D curves). In other words, if we need to visualise a parametric curve, all we have to do is to evaluate the curve's equation for increasing values of tt at some regular positions (it doesn't have to be though), and connecting the resulting positions in space to create a polygonal path (as illustrated in figure 5).
Unfortunately this is the language that you should avoid if you want to explain these concepts for beginners. Too technical, too rigid, too dry. I sort of understand what it says, but it could be done in much simpler way. I'd put it this way:
"We have a function that describes the bezier curve. If you call that function with the P1-4 parameters you will receive X,Y (or Z if you do 3D) coordinates that you can easily plot and connect with straight lines. You also need to specify how many segments you want to receive, this will be resolution of the curve."
Or something like this. Better explained ( betterexplained.com/calculus/ ) does a good job at this and I recently recently rediscovered Kirupa, I love his tutorials: https://www.kirupa.com/html5/animating_with_easing_functions...
Another good tutorial, more specific to OpenGL, is this one: http://www.songho.ca/opengl/index.html I liked this one because each lesson has a binary you can download and run on your computer (only tested on Mac).