hashbrown

04-18-2017, 10:23 PM

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:

https://s27.postimg.org/ut3tzcjhv/error.gif

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

BUT, when I rotate in the third axis: Z, the image does not rotate the way I expect it to:

https://s27.postimg.org/ut3tzcjhv/error.gif

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