I’ve been trying to understand how orthographic projection and matrices work. Not just blindly using GLM. I’ve managed to build my own poorman’s math lib, move an object, scale, and rotate in 2 Axis.
BUT, when I rotate in the third axis: Z, the image does not rotate the way I expect it to:
If I DO NOT multiply the model matrix with the projection matrix, then I see the model rotate in the Z axis properly. This issue only happens when I multiply my model matrix with the projection matrix. It’s worth noting that every other rotation, translation and scaling works as expected when multiplying with the projection matrix. This visual issue only happens rotating in the Z axis.
I’m writing everything in JavaScript and using column first matrices. This is my projection matrix:
var proj = [
2/ (right - left), 0, 0, 0,
0, 2 / (top - bottom), 0, 0,
0, 0, -2 / (far - near), 0,
-((right + left) / (right - left)), -((top + bottom) / (top - bottom)), -((far + near) / (far - near)), 1
];
this is how I’m initializing my projection matrix. The canvas size is 640x480:
var aspectRatio = Renderer.gl.canvas.clientWidth / Renderer.gl.canvas.clientHeight,
canvasWidth = (Renderer.gl.canvas.clientWidth / Renderer.gl.canvas.clientWidth) * aspectRatio,
canvasHeight = (Renderer.gl.canvas.clientHeight / Renderer.gl.canvas.clientWidth) * aspectRatio;
mesh.projection = Mathf.ortho(-canvasWidth, canvasWidth, -canvasHeight, canvasHeight, -1.0, 1.0);
Translation Matrix:
// Translation works even with orthographic projection.
Mat.translate = function (x, y, z) {
var tr = Mat.identity();
tr[12] = x;
tr[13] = y;
tr[14] = z;
return tr;
};
Scale Matrix:
// Not using right now, but when I do it works perfectly even with ortho projection
Mat.scale = function (x, y, z) {
var r = Mat.identity();
r[0] = x;
r[5] = y;
r[10] = z;
return r;
};
Rotation Z Axis.
// Rotates in the Z axis properly IF I don't multiply with orthographic projection.
Mat.rotateZ = function (degree) {
var r = Mat.Identity(),
angle = Mat.degToRad(degree),
cos = Math.cos(angle),
sin = Math.sin(angle);
r[0] = cos; r[1] = -sin;
r[4] = sin; r[5] = cos;
return r;
};
…and this is where I compute my model and projection matrices before sending the final matrix to the GPU.
this.model = Mat.Identity();
// Set Matrices
this.translation = Mat.translate(this.x, this.y, this.z);
this.scale = Mat.scale(this.sx, this.sy, this.sz); // Not using yet
this.rotationZ = Mat.rotateZ(this.angle);
// Model Matrix
this.final = Mat.mul(this.final, this.translation);
this.final = Mat.mul(this.final, this.rotationY);
// Projection
this.final = Mat.mul(this.final, this.projection);
Renderer.gl.uniformMatrix4fv(this.modelUniform, false, this.final);
Renderer.gl.drawElements(Renderer.gl.TRIANGLES, 6, Renderer.gl.UNSIGNED_SHORT, 0);
I’m really trying to figure out why I’m unable to rotate on the Z axis properly. Every other transformation works perfectly along with the projection. Thanks in advance, hopefully I’ve provided enough detail. Oh and if you want to see my matrix multiplication implementation, here it is:
https://gist.github.com/anonymous/1fdc609d56264fb389f6f4deeef521ae