🖥️ Random Computer Graphics Notes

🖥️ Random Computer Graphics Notes

This page may contain a bunch of grammer & spelling mistakes but ill fix it later.

Random notes & interesting topics I find while learning computer graphics will go here!
For example, A topic I wondered for so long while playing games is why crosshair colors always max at 255? & even colors in general in any applications (photoshop, paint whatever coloring garbage all has the same idea). I was very curious about it for a while, so when I did my raytracer I learned about the RGBA color model (I was blown away at first, it’s simple but amazing in how it works) & then I wrote a post just about it in the raytracing post, this example of something I find interesting will go in here, since it was something I was very curious about & wanted to know the reasoning behind it.

These things are not really “known” to me because I didn’t learn computer science (binary, ALU, CPU cache stuff, how memory works whilst programming, etc). My university curriculum was trash so I barely studied any real “low level computer science” stuff. So whenever I see CS stuff I get happy, maybe later I’ll do a masters in CS just to learn CS properly.


Learning about performance (Cache Miss & Hits, not in detail!)

While reading on Row vs Column Matricies, I came across a performance comparison between the two, since Row matrix multiplication is obviously garbage just like little endian, I noticed the term “Cache Miss” & “Cache Hit” being used, I have heard the term many times before but to summarize since row matrix multiplication will multiply the following like so:

    class Matrix44 
    {   //Language will always be C++ & only C++ from here on forward 
        //(should be atleast, unless I specificy whilst trying to explain something).
        
        //Creating the matrix
        float m[4][4]; //4*4 = 16, 16 coefficients will be in the matrix
    };  

coefficients in memory = c00, c01, c02, c03, c10, c11, c12, c13, c20, c21, c22, c23, c30, c31, c32, c33

x prime is achieved by multiplying the x from the 1st element of 2D array of matrix M, then 5th, then 9th & so on for the other y & z primes.
x’ = x * c00 + y * c10 + z * c20
y’ = x * c01 + y * c11 + z * c21
z’ = x * c02 + y * c12 + z * c22

since we are not sequentially accessing elements from the array this is not ideal, & could degrade cache performance in the CPU, resulting in cache misses. I heard this term many times but never really knew what it meant, I already knew that accessing memory sequentially was good, but didn’t know the terms Cache Miss & Hit had to do with it, good to know now I guess.

“We won’t go into too many details here, but let’s say that the closest memory that the CPU can access is called a cache. This cache is very fast to access but can only store a very limited number of data. When the CPU needs to access some data, it first checks if it exists in the cache. If it does, the CPU access this data right away (cache hit), but it doesn’t (cache miss); it first needs to create an entry in the cache for it, then copy to this location the data from the main memory. This process is more time-consuming than when the data already exists in the cache, so ideally, we want to avoid cache misses as much as possible. Additionally, when copying the particular data from main memory, the CPU also copies a chunk of the data that lives right next to it (for instance, the next 24 bytes) because hardware engineers figured that if your code needed to access an element of an array, it was likely to access the elements following it soon after as well. Indeed, in programs, we often loop over elements of an array in sequential order, and this assumption is likely to be true. Applied to our matrix problem, accessing the coefficients of the matrix in nonsequential order can therefore be a problem. Assuming the CPU loads the requested float in the cache plus the 3 floats next to it, our current implementation might lead to many caches misses since the coefficients used to calculate x’ y’ and z’ are 5 floats apart in the array.” -scratchapixel

Column Major multiplication looks like this
x’ = c00 * x + c01 * y + c02 * z
y’ = c10 * x + c11 * y + c12 * z
z’ = c20 * x + c21 * y + c22 * z

Now just imagine, all the performance your missing out on if you use row major multiplication when you can just use column major, also by now it should be stated that everything in graphics in terms of transformation, scale, rotation, projection matrix, & etc. Is done through matricies so you can imagine doing all that every single frame (Forgot to mention, even if row is used, since the compiler is so jacked it will be smart and will not miss, as usual mr compiler doing everything), I noticied that homogenous coordinates are normally taught in column major as well so I guess thats the reason, but anyway this debate seems something like little endian vs big endian except that it’s important for everyone to learn the difference between row & column major.

Going off topic a little, but still important, knowing how elements are storied in a 2d array is important so you know whats happening in the matrix, for example: In row-major order, the elements of a multi-dimensional array start from left to right then top to down, in C & C++ will look like this:

    float m[2][3]= { {1, 2, 3} , {4, 5, 6} }; 
        for(auto& a: m)
            for(auto& b: a)
                std::cout<<b<< " > ";
                //1 > 2 > 3 > 4 > 5 > 6 > 

In column-major order, which is used by languages such as FORTRAN and MATLAB, they store from top to down then left to right so the result will look like this instead:

    //1 > 4 > 2 > 5 > 3 > 6
Juma Al Remeithi

Juma Al Remeithi

Game Developer & Graphics Enthusiast