[0]: https://pikuma.com/courses/learn-3d-computer-graphics-progra...
[0]: https://pikuma.com/courses/learn-3d-computer-graphics-progra...
People pay for a specific teaching style and that's absolutely fine.
If anyone's looking for motivation, I made a wasm-compiled demo of the renderer you produce by the end - https://rmshin.github.io/3d-renderer-wasm
Instead, I’d recommend
https://learnopengl.com/ https://raytracing.github.io/books/RayTracingInOneWeekend.ht... https://fgiesen.wordpress.com/2011/07/09/a-trip-through-the-... https://foundationsofgameenginedev.com/ https://youtu.be/j-A0mwsJRmk
Though, if you really do want to put pixels, this is how you should do it: https://gist.github.com/CoryBloyd/6725bb78323bb1157ff8d4175d...
On that I cannot recommend enough is this github repo:
https://github.com/ssloy/tinyrenderer/wiki/Lesson-0:-getting...
If you are more of a visual learner, this guy is also a treasure trove:
This is the opposite of what you would hope to see for learning graphics programming.
For example, area fill algorithms are really interesting. Etc.
Programming comes from a place of first principles, the goal being to understand what is needed completely so that a solution that meets many parallel constraints can be constructed.
Coding comes from a place of completing a task, the goal being to get from the requirement to the operating task in as short a time as possible so that one might move on to the next task.
Both disciplines have value. The original question was unclear about where the author hoped to end up.
To put this in a slightly different perspective, a graphics programmer can write a program to show a shaded object on any platform with a CPU and a way to display graphics. A graphics coder can write a program to show a shaded object only on those platforms where they have previously mastered the APIs for generating display graphics.
Programming refers to the act of writing a program for a computer to follow.
Coding refers to the act of writing code for a computer.
Edit: The definitions are not commonly used this way and in fact I've heard other people even give opposite definitions to what correponds to which word.
But if your goal is to program a modern shader on a modern platform (even if it's a 2D graphic), you should learn a modern graphics library.
-------
A modern graphics API is laid out the way it is: to maximize modern performance on modern systems. A first principles bottom up approach will absolutely cover shaders (maybe compute shaders are easiest?)
The argument against "just" using the hardware is that the hardware resists learning that conceptual skeleton. Instead of learning how a rasterizer is implemented, you learn the specific API incantation to bring one up, and that has changed a lot over the years in the direction of being a more professionalized phenomenon, so now it's much easier to start application top-down, from within a premade rendering environment like a game engine or Blender's rasterizers.
Learning to work on production rendering engines would involve reading and studying existing implementations, reading the relevant research papers along the way.
The graphics pipeline from geometry -> vertex shader -> pixel shader -> image is the damn point.
When the literal hardware is laid out in a certain way, you must learn that hardware layout and understand it. These API 'incantations' as you put it aren't high magic. They logically flow from the requirements of modern graphics programming.
If you just skip that stuff, you won't ever learn about modern GPUs, modern CPU->GPU data transfers, GPU parallelism or how a CPU calls the GPU routines to render.
Maybe you can make the argument that you should learn rasterizing first to simplify the learning process. But I would argue that it's easy enough to learn rasterizing when you get to the Pixel Shader step.
> The argument against "just" using the hardware is that the hardware resists learning that conceptual skeleton. Instead of learning how a rasterizer is implemented, you learn the specific API incantation to bring one up, and that has changed a lot over the years in the direction of being a more professionalized phenomenon, so now it's much easier to start application top-down, from within a premade rendering environment like a game engine or Blender's rasterizers.
The argument against that is that you eventually have to learn today's hardware anyway. So you might as well start now.
Tomorrow's hardware is based on today's hardware. And today's hardware is based on yesterday's hardware.
It's all incremental progress. I'd personally say that OpenGL with GLSL might kinda sorta look like modern stuff (vertex and pixel shaders), but anything older (ex: 90s BitBlits) is so old it's just completely a waste of time.
(Sorry, this probably sounds more critical than I'm intending...)
You may think this is redefinition. It's not. This is how both terms originated. A "coder" did the unskilled gruntwork of implementation for business projects, while a programmer was holistic.
> I find it bizarre that people now use the term "coding" to mean programming. For decades, we used the word "coding" for the work of low-level staff in a business programming team. The designer would write a detailed flow chart, then the "coders" would write code to implement the flow chart. This is quite different from what we did and do in the hacker community -- with us, one person designs the program and writes its code as a single activity. When I developed GNU programs, that was programming, but it was definitely not coding.
> Since I don't think the recent fad for "coding" is an improvement, I have decided not to adopt it. I don't use the term "coding", unless I am talking about a business programming team which has coders.
https://stallman.org/stallman-computing.html
In this case, it is you, and the wider cottage industry of business "coders" who are doing the appropriation. It's not your fault. The bootcamp or Super Cool Totally Serious College you likely learned from probably used the term "coder" alongside words like "rockstar!" You were given a bad definition, and never knew any better at all. ChuckMcM's comment, on the other hand, is correct. Using the word "literally" to mean "figuratively," while colloquial, is still less correct than figuratively.
The phrase "code monkey" is not a compliment, and didn't come from nowhere. It came directly from these pre-existing definitions.
Programming requires logic. If you are coding, the thinking's already been done for you. You are just doing unskilled labor akin to data entry to get the computer to actually follow the instructions.
It's a shame because there's a nice flow to coding once you got everything nailed down. Coders are no different from (human language) translators and like good localizers, a really good "coder" understands the subtleties of the language. If your application is concerned about scalability or performance or cross-compatibility, you aren't just googling an API and pasting in commands to get something working.
But I guess coding may not really be a thing in the next few decades if AI really does catch on.
The other issue is that not everyone learns well from the bottom up. I believe that top down is a much better way of learning anything, and lets you progressively get closer to first principles while not discouraging learners with a steep difficulty curve. But unfortunately is an approach that is seldom facilitated by anyone.
> You'll learn how a software 3D engine works under the hood, and ... write a complete software rasterizer from scratch
Writing a software rasteriser is a fantastic way to learn the classic graphics pipeline, Every single aspect of said pipeline offers scope for one to learn more about how GPUs work, and the algorithms behind them. This would be immensely educational to a new graphics developer.
Vertex processing, including fast, efficient file parsing, vertex data layout and storage, and optimisation.
Fast primitive assembly from vertices, including line-drawing and interpolation algorithms.
Texture mipmapping, and mapping.
The rasterisation phase itself offers tons of opportunity, from Bresenham's line drawing algorithm to supersampling, tiled rendering, parallelisation, and efficient memory layouts for cache locality.
Clipping, culling, hidden-surface removal, z-buffering, and stencil tests.
Various other algorithms that are taken for granted with a pre-existing graphics pipeline, like texture lookup, vector reflection, environment mapping.
Post-processing and miscellaneous algorithms like anisotropic filtering, multi-sample anti-aliasing, temporal anti-aliasing, and even deferred rendering.
Graphics programming skill (by 'skill', I mean being able to write a shader pipeline that both satisfies the art direction and performs well), on the contrary, is very deeply tied to a good understanding of hardware. Especially now that the new APIs (Vulkan, Metal, D3D12) are purposely less abstracted than their predecessors.
Neither.
>the nature of GPU architectures means you are forced to deal with super low-level details from the very beginning.
Not everyone is trying to push the hardware to its limits by making the best thing possible with the hardware. Plenty of projects can get along fine with a A/AA renderer or with unoptimized shaders.
>there's no operating system to manage threads
There literally is. Or if you disagree the firmware manages the threads.
I'm not entirely sure I agree in the modern day sense. Especially if our analouge is webdev. So much of industry is using UE and Unity that you probably can be a "graphics programmer" professionally without ever knowing what a vertex buffer is (only slightly exaggerating). Your ultimate job is either to a) make images look better b) make images run faster or c) make sure images can get put into the engine properly. And a high level understanding and implentation of shaders/texturing concepts and understanding which settings run slower on those engines (even if you can't explain them in detail) can get you pretty far in those regards.
you're certainly SOL once you move out of your engine of choice, but you can definiely be productive enough to get hired if you got a foot in the door.
Teaching beginners to render graphics without the GPU is like teaching them to do fractional math without the FPU. It won't make their first project better and gives them the wrong idea of what to expect.
> This is the opposite of what you would hope to see for learning graphics programming.
It is exactly what you would hope to see.
And I would dare say I'm a graphics programmer, mostly self taught.
When I started, as a teenager, in the late 80's, there were no GPUs. So I learned everything from first principles. I recall implementing Bresenham in x86 assembly for my CGA card. And then, as a follow up, rasterizing a triangle. You really had to understand stuff end-to-end then as the hardware was so slow. I.e. even C was too slow for that stuff.
And today, still, the best offline renderers, that produce the images you see on the big screen, are CPU-only. 100% custom code, no 3rd party API dependency.[1]
If you write stuff for CAD/CAM/CAE/VFX, there is a big chance you do not think about the constraints of a GPU and less so of one of the APIs used to program it. Except for previewing stuff.
I would suggest to anyone learning graphics programming (or anything else for that matter) to do so from first principles.
GPUs are specialized hardware for realtime applications. That is very specific. I don't say don't learn that. But I suggest to not start with it.
[1] One of my best friends is the lead developer of the 3Delight renderer.
Like any student engineering project, "baby's first rasterizer" would emphasize a combination of concepts and motions - a path to take, to get to a result that can be tested. We don't even have to use Bresenham now - deriving the rasterized line from linear interpolation is mathematically more sound and no sweat for modern CPUs. But it might be pedagogically useful to compare the two to explain quality vs performance tradeoffs, ones that were made historically and those that are still in use today.