You take a point and figure out if it needs to be colored differently based on certain criteria. Like if it was in shadow, or if it's being hit by a bright light, or you just want a sepia tone across everything. You can even shift everything. Take the screen and distort it according to some kind of function. Like make it all wavy.
3d games are no more or less conceptually different than 2d games in a lot of regards. There are more things to track and be aware of, but you're effectively doing a lot of the same things.
If you've ever messed around with making 2d games, you can even begin simple experimentation by just making another layer of depth. Like LittleBigPlanet, it's ostensibly a 2D game presented with 3D graphics. But it allows you to shift between 3 layers to give you some depth.
No, shaders are always done by the 3d card =)
Effectively, a shader is no different than any other bit of code you have. Anything you can do in a shader you can do on the main program thread (and vice versa). Now, things you typically want to do with a shader are better done by the GPU for various reasons. Better floating point math processor, pipelines more suited for the task, etc.
And you can make the shaders generic enough to reuse for multiple applications. Basically the shader says "Hey, here's where the light source is, here's the luminosity, here's the color, here's what it is shining on, here's how the color changes."
And being essentially dedicated number crunchers, people realized that not everything sent to a graphics card needed to actually render. You could make a shader to do something crazy, like solve complex equations more quickly than a generic CPU could. So if this was 8 years ago, you might decide to write a shader that could effectively mine bitcoins. Which is what people did and why good graphics cards have become crazy expensive.
Basically, I knew I was going to be slightly wrong about something somewhere.
I mean, effectively anything you can do with a GPU shader, can be done by the CPU, so it seemed reasonable to me that you could make something functionally equivalent for the CPU and call it a shader.
It started feeling like the difference between "programming language" and "scripting language" in my head.
https://blog.chromium.org/2016/06/universal-rendering-with-s...
The classic OpenGL 1 framework had no shaders and a static pipeline. Its straightforward in doing things but reduces the amount of fancy things you can do. Maybe check out a guide like here[1].
[0] http://www.adriancourreges.com/blog/2016/09/09/doom-2016-gra...