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.
> 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.