I’ve always wanted to get into graphical programming but I always get hung up on creating anything. Shaders feel like black magic to me. And the tutorials are spread across many different technologies and techniques that it’s hard to determine where you should start.
Build a raytracer from scratch. It's a couple hundred lines of very straightforward C code, or much, much less with a higher level language. You will learn _a ton_ about the rendering pipeline, transformations, lighting, shading surfaces, etc. It is super satisfying the very first time you run and finally get some colorful shaded spheres floating in space--you'll remember that moment for a long time. This is just one of many resources to help get started with a raytracer: https://www.realtimerendering.com/raytracing/Ray%20Tracing%2...
To get a quick feel for ray tracing, I would also suggest https://rayground.com/. It has a lot of ray tracing projects, ranging from basic samples to complicated scenes. They can all be run in your browser.
I saw that book but was confused on the way to use it. Are you supposed to follow along and turn the pseudo code into a real implementation? Or is meant to be Passively read while perhaps taking notes?
Shadertoy is the absolute worst way to learn graphics. It's a puzzle designed for experts to show they can pass the puzzle. Production graphics almost never use those techniques. Production graphics don't limit themselves to fragment shaders and 1 draw call and no vertices. Production graphics run at 60 fps full screen where as shadertoy graphics almost never run at 60fps even in their tiny display.
Shadertoy can be fun and you can learn lots of techniques and lots of math but you aren't learning graphics
Usually I teach the OpenGL pipeline in one session, but students have a lot of things to understand: Vertex shader has its own things to learn and without the fragment shader you do not see what you are doing.
In the following lessons I dig into the details of each part independently. This approach works, but it requires a lot of abstraction from the beginnings and a lot of code to have trivial applications. Furthermore, it introduce latency in understanding the whole pipeline, they do not really 'get' why we have this pipeline and what each bloc does inside of it. Only after a few lessons, when they have all the pieces, everything clicks.
This year I tried another approach: I used at the first lesson exclusively ShaderToys with progressive exercices, the students were very happy to be able to create content directly and eagerly digged into the details by themselves.
Naturally, as wanted, they felt the issue of not being able to create simple objects like a 3D cube and move in 3D.
The second lesson was then the perfect time to show the whole pipeline and the vertex shader was an almost obvious need!
Another change I made this year was switching from C++ to Javascript, I'm not yet sure which solution is the best. They both have advantages and drawbacks to learn OpenGL/WebGL.
I second this recommendation. It's the perfect space to play around with things and see instant results, which is very important for learning (quick feedback).
I recommend 'the art of code' on youtube:
https://www.youtube.com/c/TheArtofCodeIsCool/playlists
He shows step-by-step how to create some pretty amazing effects in shadertoy.
Try to find a small and unusually talented team doing what you want to learn, and get hired by them. There is no substitute to learning from smart/experienced people.
(This is after learning the basics + the intermediate stuff.)
This sounds like great advice that's very difficult to follow. How do you find a small and unusually talented team? And if you don't yet have the required skills, how do you get hired by them?
Graphical programming is a blast. I can totally see how it feels overwhelming, especially with a lot of ways to do the same thing. I will say though that once you get started a lot of the knowledge is transferable to different technologies and methods. I tend to recommend that people start with The Book of Shaders [0].
What kinds of things would you ultimately like to make?
I tried the book of shaders but I think I got stuck when it got into the algorithmic drawing. I kept on getting confused on each individual line and how it fit into creating the whole picture especially when smoothstep() is involved.
As for what I want to make, nothing in particular right now my end goal is perhaps to get a job as a graphical programmer somewhere.
Yeah, that makes sense. There's some mental gymnastics involved in writing shaders since you're writing the code from the perspective of an individual pixel. As opposed to other methods like using Processing or the HTML canvas where you can just say "draw a square from here to here and make the lines this thick". When writing a shader, I have think instead "Ok, if I want a line here, and I was a pixel on that line, what would I need to know to determine my color".
If you're finding that to be the obstacle with shaders, it may be helpful to start with just learning a library like Processing, or general graphics library in whatever programming language you're comfortable with, and then come back to shaders. It will still take changing how you think about things, but then you'll have some solid foundation.
Personally, I've found it the most helpful to have some kind of goal in mind. Some kind of image or style that I want to make, then figure out what techniques I need to learn to get there. Starting from the technical side can work, but then it can be easier to loose interest when things get challenging. When I start with an artistic vision, then I often find myself over my head in the technical things I need to learn, but I feel motivated to push through that to get to the end goal.
I mean they are a bit. They are programs that fit pretty arbitrarily into other parts of the rendering pipeline. I recommend starting with Compute Shaders as those end up being just a big parallel map on your dispatch size. A lot less pipeline to understand.
The other key thing to understand, is that a GPU is across a network (PCI-X network generally) So when you call dispatch, your generally sending a message (encoding a command in a command buffer) to do the work later on on a different device.
the dispatch size (x, y, and z) are multiplied by the numthreads components (Some compiler SIMD stuff requires this) And that sum total threads (x * y * z) are launched. the index of the thread this particular invocation is launched on is left in threadIdx, you can then use that index to read and write from other buffers.
This is HLSL, but the same generally applies to most APIs. Then more of this just becomes implicit and behind the scenes for shaders dispatched in other contexts, since more is known implicitly about the context, and more is done by other units of the hardware.
Start with unity, make an unlit shader, start doing basic effects (in colours, then using texture samples) using uv coordinates. (In frag, ignore vertexes to start with). Just remember youre just colouring a pixel, on a bit of a surface.
I wouldnt use line count as a metric to judge how sensible an approach it is for learning how to get into graphics programming.
The OP already cited shaders as one avenue, and shaders are so so easy to get immediate results from; as opposed to making a small mistake in a path tracer and spending hours debugging why your screen just shows one colour.
Need to debug where youve gone wrong with a shader? Return float4(uv,0,1) and its working again.
I love this little newsletter! Always a pleasure to see it arrive in my inbox, usually has at least one or two really interesting articles in it. Highly recommended!