Graphics Pipelines for Young Bloods
jeremyong.com
jeremyong.com
Downside is of course transparency and the need to dump your full material model into a G buffer...
> While we lose a bunch of work that hardware may have done for us, cutting the pipeline here
From what I’ve read, modern GPUs have moved most of this work from fixed function hardware to implicitly inserted shader assembly. So, we’re on the hook for manually writing that code. But, it’s not missing out on as much hardware magic as one might think.
If I understand correctly, there has been so much focus of cramming general compute into GPUs that the fixed function hardware for pixel work has been stripped down to visibility rasterization, barycentric generation (accessible through the SV_barycectric instruction), and texture sampling (given coordinates and derivatives).
The general trend has been towards having general compute yes, but check the ISA and read your shader disassemblies before drawing any conclusions.
I just don't get it. I don't get how the matrix operations somehow magically work out. I don't get how it is that light bouncing/reflectivity works itself out in any reapectable amount of time. It all just sounds like a bunch of jargon, jumbled together, and pretty arrangement of pixels comes out.
Like I get the camera being set in a scene. I get it forms a frustrum with everything in the field of view. I get that you have a bunch of geometry in it's own independent coordinate systems, that are then glued together by transformation matricies.
I get U, V, W unwrap basically taking a 2D texture and mapping it to a 3D model. I get annotating fragments with material properties to aid on subsequent processing passes treating using linear trajectories and other Voodoo to figure out where reflections, shadows, and brightening should occur, and that part of what makes all of that doable is massively parallel co-processing devices divide and conquering the processing, which are orchestrated from the host system's memory space through driver API's.
But that's where my internal stack blows out.
There's two secrets to this. The first trick is remembering what matrices do to vectors, boils down to equations of this form:
x' = M[0] * x + M[1] * y + M[2] * z
y' = M[3] * x + M[4] * y + M[5] * z
z' = M[6] * x + M[7] * y + M[8] * z
I won't write the function for matrix/matrix multiplication, but when we invented it, we chose a function that's associative with respect to matrix/vector multiplication. That means that Ma * (Mb * v) = (Ma * Mb) * v. This turns out to be a very good property, because we can then "collapse" every single linear transform we ever want into a single matrix. Stack these however high you want: (Ma * Mb * Mc * Md * Me * Mf * ...) will always collapse down to a constant number of numbers.In computer graphics, we tend to have a few "standard" matrices converting up the chain of spaces like this:
vProjectiveSpacePosition = mProjectiveFromView * mViewFromWorld * mWorldFromModel * mModelFromBone * vBoneSpacePosition
And you can add your own if you want!The second thing is that we cheat when it comes to perspective. The "correct" way to think about it is that your 4x4 matrix transforms into a 4-dimensional space known as "projective space" where parallel lines meet at some point.
But that's confusing, the better way to think about it is that we can't elegantly represent perspective with just 3 coordinates, so we cheat and add a weird fourth one. Don't worry about it too much, the math is mostly handled by higher-level libraries. Once you need to figure things out yourself, you should be able to learn what you need to learn. But for now, just get comfortable with the above.
> I don't get how it is that light bouncing/reflectivity works itself out in any reapectable amount of time
We actually don't do "light bouncing" in real-time, we typically emulate it. Think of it like this: if you shoot a bunch of light rays at a thing in the real world and measure the light back, you'll come back with a bunch of light reflected back (towards a sensor, but it could also be towards your eye).
Now try to curve fit that data to some equation. That's one of the most popular models for object materials, "Trowbridge-Reitz": https://www.desmos.com/calculator/8otf8w37ke . In practice, it's a combination of curve fitting to real-world data and a lot of smart people thinking about how to make it make physical sense. This models parameterized to work on some known set of materials (the working theory is "microfacets", which are tiny grooves on an object assumed to be mirrors). There are other models you can have, too, but this is the workhorse of the games industry.
To get reflections, we play tricks: pre-compute the incoming light for a given reflection vector, so it doesn't have to be done at runtime. But this comment is already long enough. Contact info is in profile if you want to ask me more questions.
In practice, it’s just a ton of hacks to estimate this value. It turns out if you do this reasonably accurately across all pixels and surfaces you get a pretty picture. Anything else is just optimization.
Read PBRT to learn how basic irradiance estimation should work and then rasterization becomes less about understanding the goal and more about understanding the hacks needed to achieve the goal in real time.
I feel like backend dev has turned my brain to mush and I miss the math we used to do in university.
Seems there a very few jobs in software dev where you actually get to use math/complex algorithms, graphics being one of them.
This all happens independently of the actual kernels/shaders we dispatch on the GPU itself (where the 3d math and all that comes into play). There are definitely rendering programmers that specialize more in the stuff above though.
but i think all of these are incidental complexity brought on by the physical world, practicality of the hardware and api calls.
The _actual_ complexity in graphics rendering is the maths required,as well as understanding of the physics/modelling of the materials etc, and how to cut down unnecessary computation etc to achieve the framerate target.