Whether you use fixed or programmable shader pipeline, a common vertex pipeline consists of this matrix multiplication (either custom coded or behind the scenes):
Projection * Modelview * Position
Lots of tutorials note items such as an object’s rotation should go into the Modelview matrix.
I created a standard rotation matrix function based on degrees and then added to the degrees parameter the proper multiple of 90 to account for the screen’s autorotation orientation. Works.
For different screen sizes (different pixel widths and heights of screen), I could also factor a Scale multiplier in there so that a Modelview matrix might incorporate a lot of these.
But what I’ve settled on is a much more verbose matrix math and since I’m new to this stuff, I’d appreciate feedback on whether this is smart.
I simply add independent matrices for the screensize scaling as well as the screen orientation, in addition to object manipulation such as scale and rotation. I end up with this:
Projection * ScreenRotation * ScreenScale * Translate * Rotate * Scale * Position
Some of these are interchangeable order, such as Rotate and Scale could be switched, I find.
This gives me more fine-tuned control and segregation of code so I can concentrate on just an object’s rotation without thinking of the screen’s orientation at the same time, for example.
Is this is a common or acceptable strategy to organize matrix math appropriately? It seems to work fine, but are there any pitfalls to such verbosity?
The main issue with such verbosity is, that it wastes precious computation cycles if performed on the GPU. Each matrix would be supplied as a uniform, thus forcing the GPU into computing for each and every vertex, while it would be actually a constant across the whole shader. The nice thing about matrices is, that a single matrix can hold the whole chain of transformations and transformation can be done by a single vector-matrix multiplication.
The typical stanza
of using two matrices comes from, that usually one needs the intermediary result of
Modelview · Positionfor some calculations. In theory you could contract the whole thing down toNow you’re proposing this matrix expression
Ugh… this whole thing is the pinnacle of unflexibility. You want flexibility? This thing is rigid, what if you wat to apply some nonuniform scaling onto already rotated geometry. The order of operations in matrix math matters and you can not freely mix them. Assume you’re drawing a sphere
looks totally different than
Screen scale and rotation can, and should be, applied directly into the Projection matrix, no need for extra matrices. The key understanding is, that you can compose every linear transformation chain into a single matrix. And for practical reasons you want to apply screen pixel aspect scaling as last step in the chain, and screen rotation as the second to last step in the chain.
So you can build your projection matrix, not in the shader, but in your display routines frame setup code. Assume you’re using my linmath.h it would look like the following
The resulting matrix
projectionyou’d then set as the projection matrix uniform.