[SOLVED] 3D Rotations with a Shader matrix or a matrix (GLSL ES)

Edgamer63

Member
Hello, i was wondering on how do i can do to make rotations with a shader matrix or something to do rotations in 3D using just a vertex_submit and the required rotations setted in the uniforms of a Shader... I already do my own translations with a shader, but i need info to do a vertex rotations (Yaw,pitch, Roll).

Before i do this with the d3d functions... but seems to not work with the 3 rotations SETTED (d3d_transform_set_rotation_x...y...z) . Also do a good rotation system with ADD ROTATION(d3d_transform_add_rotation_x...y...z) once, but this causes the disk overwork.... so i think if a vertex and a set shader will do it lightly and with minor disk usage (Task Manager)... Creating only one model ONCE to doing well to disk.

I've Found good info... but i want help to understand it :)
"https://learnopengl.com/Getting-started/Transformations"

Also I got Some Real Good Clues... But i don't know yet on how to apply this... if i can, i will see if i can do it and post it somewhere:



Also A good and awesome c++ tutorial:


~I don't understand yet the rotations... also the translations i worked it with .xyz of a shader... so, i have not an idea yet of how to do a rotation, but have good clues and videos (Keep Studying).

And some Rotation vids in khan Academy:

"https://www.khanacademy.org/math/linear-algebra/matrix-transformations"

Also is a interesting Match no? :D

PD: I can't post it advanced programming... Why? :'v
 
Last edited:

jo-thijs

Member
PD: I can't post it advanced programming... Why? :'v
The reason is explained in the first sentence on the pinned thread in the advanced programming section:
https://forum.yoyogames.com/index.php?threads/advanced-programming-discussion-forum-rules.25591/

Hello, i was wondering on how do i can do to make rotations with a shader matrix or something to do rotations in 3D using just a vertex_submit and the required rotations setted in the uniforms of a Shader... I already do my own translations with a shader, but i need info to do a vertex rotations (Yaw,pitch, Roll).

Before i do this with the d3d functions... but seems to not work with the 3 rotations SETTED (d3d_transform_set_rotation_x...y...z) . Also do a good rotation system with ADD ROTATION(d3d_transform_add_rotation_x...y...z) once, but this causes the disk overwork.... so i think if a vertex and a set shader will do it lightly and with minor disk usage (Task Manager)... Creating only one model ONCE to doing well to disk.

I've Found good info... but i want help to understand it :)
"https://learnopengl.com/Getting-started/Transformations"

Also I got Some Real Good Clues... But i don't know yet on how to apply this... if i can, i will see if i can do it and post it somewhere:



~I don't understand yet the rotations... also the translations i worked it with .xyz of a shader... so, i have not an idea yet of how to do a rotation, but have good clues and videos (Keep Studying).

And some Rotation vids in khan Academy:

"https://www.khanacademy.org/math/linear-algebra/matrix-transformations"

Also is a interesting Match no? :D
So, what you're asking for is:
- given a Yaw, a Pitch and a Roll value, how to construct a matrix that represents the rotation described by these values?

Hm, do those describe a unique rotation?
Is there a fixed oder in which the yaw, pitch and roll rotations are applied?
If so, then what base orientation and position do you want to use to rotate around?
Is the yaw always aroun the z-axis, the pitch always aound the y-axis, the roll always around the x-axis and the position always the origin?
If so, you can just multiply the 3 matrices given in the picture you posted.
 
If you go about using the rotation matrices in that diagram that in a left-handed coordinate system, they will result in clockwise rotations when looking toward the origin from the positive direction around the axis of rotation. If that is opposite what you expect, then reverse the sign in front of the sin functions.

It's hard to know what information you require exactly. Are you just looking for an explanation of how rotation matrices are multiplied together to produce more complex rotations?
 
When you combine rotation matrices you use matrix multiplication. And the order in which you do the multiplication will affect the outcome.

Let's take a look at a matrix multiplication between two 3x3 matrices:
upload_2019-3-22_9-50-58.png
One cell is highlighted in the resulting product of (A*B). The diagram shows how the value for that cell is computed based on the corresponding row of the left matrix (A), and the corresponding column of the right matrix (B).
It is basically just a dot product between the vectors formed by those corresponding row and column. The computation for all the other cells of (A*B) work similarly, the upper-left cell would be the dot produce between the top row of A and the left row of B.

For example, let's say you want to first do a "roll" around the x axis, and then a "pitch" around the y axis, and finally a "yaw" around the z axis.

The following corresponds to a rotation around the x axis, and then a rotation around the y axis.
Code:
 y rotation        x rotation      y*x rotation
┌              ┐┌             ┐   ┌                    ┐
│ cy  0 -sy  0 ││ 1  0   0  0 │   │ cy  sy*sx -sy*cx 0 │
│ 0   1  0   0 ││ 0  cx  sx 0 │ = │ 0  cx      sx    0 │
│ sy  0  cy  0 ││ 0 -sx  cx 0 │   │ sy -cy*sx  cy*cx 0 │
│ 0   0   0  1 ││ 0  0   0  1 │   │ 0   0      0     1 │
└              ┘└             ┘   └                    ┘
And now, a z rotation is added. The order of rotations here is, x then y, then z.
Code:
 z rotation      y*x rotation             z*y*x rotation
┌              ┐┌                    ┐   ┌                                          ┐
│ cz  sz  0  0 ││ cy  sy*sx -sy*cx 0 │   │ cz*cy  cz*sy*sx+sz*cx -cz*sy*cx+sz*sx  0 │
│-sz  cz  0  0 ││ 0   cx     sx    0 │ = │-sz*cy -sz*sy*sx+cz*cx  sz*sy*cx+cz*sx  0 │
│ 0   0   1  0 ││ sy -cy*sx  cy*cx 0 │   │ sy    -cy*sx           cy*cx           0 │
│ 0   0   0  1 ││ 0   0      0     1 │   │ 0      0               0               1 │
└              ┘└                    ┘   └                                          ┘
You have to think carefully about which order to do your rotations in. A lot of times, Z*Y*X works well, especially with FPS type games (presuming up is along the z axis, and forward is along the x axis).

You can combine your rotations in GML through matrix multiplication. However, if you know in advance what kinds of rotations you are doing, you can precompute the operations like I have done so above. You could just plug the resulting elements of z*y*x directly into a matrix, without having to take the steps that went into computing them in the first place.

In case there was any confusion, cx and sx correspond to the cosine and sine of the x rotation, cy and sy are the cosine and sine of the y rotation, and cz and sz are the cosine and sine of the z rotation.

Also keep in mind that there are other ways of construction rotation matrices. The fourth figure in the image in your OP is an example of one of them. It is a rotation by angle theta (θ) around an arbitrary axis R.

Finally, you might have noticed that in my example, the signs in front of the sin functions have been reversed. This is becuase I want an anti-clockwise rotation when viewed from the postiive direction of the axis of rotation in a left-handed coordinate system.

More on coordinate systems. The coordinate system is the relationship between the x, y, and z axes. Point toward +X with your index finger. Point toward +Y with your ring finger. Point toward +Z with your thumb. If you can do that with your left hand, then you have a left-handed coordinate system. If you can do it with your right hand, then you have a right-handed coordinate system. The coordinate system is determined by the view and projection matrices (as well as your display). Flip any one axis and you switch from one coordinate system to the other. The consequences of flipping a coordinate system are purely visual: your world will be mirrored, textures will appear upside down or backwards, and backface culling will be reversed.
 
Last edited:

Edgamer63

Member
So... i must understand how to use the mat4 and mat3 functions in shaders, is a MUST learn xD.

In this case: Mat4 ... and then multiply it with the operations included in mat4 rotations matrix...
 
I still don't know what you're trying to do. So I've just been giving some basic information about rotation matrices. There's a lot more to say about them, but I don't know what information would be useful to you.

It feels like you're barking up the wrong tree. So far, I'm not seeing why you can't make good use of the built-in world matrix that gamemaker already sends to your shader. As long as it's doing the work, you might as well make use of it.
 

Edgamer63

Member
Well... i try to rotate a vertex buffer ... using the "vertex_submit" while using the shader...
It's good for less usage of memory and disk... but i see that this need a bit more of work...


I have 3D Models worked with the lowest level of 3D Modelling in gamemaker, so in that way, to draw it correctly with rotations... i need to work it with matrixes maded in shaders (Due to Translations that i already worked with shaders).... is like ... the thing that last me to get a good performance of CPU and technical things :D .

I cannot work with normal "matrix_build" functions, because it will bug all things, also make the screen look very weird (already tested and fixed).
 
I suspect you have been using the matrix_build functions incorrectly.

You mention briefly the screen looking weird, which makes me wonder if you are resetting to the identity matrix afterward.
 

Edgamer63

Member
Well , i do it xD ... Do Nicely good rotations, also centered! use less disk and memory (Ram), uff... Thank you for your help :D
 

Joe Ellis

Member
It says this is solved but is it?
The matrix build function and other transformations aren't that slow, and they get calculated once per frame per instance,
but calculating it in a shader is per vertex per instance, which could be alot slower if it's a high poly model, even with the extra gpu speed,
I'd always try and use the standard gm_matrices[MATRIX_WORLD], unless you're doing something extraordinary like bending particles or some randomized effect, just use the standard gm world, and the fastest way to pass that to the shader is matrix_set(matrix_world, world_matrix)
 

Edgamer63

Member
The fact: GM 1.4 can't build entities, so it bugs if i use matrix_world... Also matrix world changes the aspect of the window (without matrix_identity)... So it do very fast with a shader, also of course works well.

Also, i tryed it before with matrix build and d3d transformations.... Still better my new method xD
 

Edgamer63

Member
Fixed rotation and a center of rotation... But i will keep working yet, is not over ...

"https://forum.yoyogames.com/index.php?threads/3d-rotation-centered-after-translating-vertex.61170/"

NOTE:
-posx,posy,posz are the translate points.
-cx,cy,cz are the center points.
-rotx,roty,rotz are the rotation angles.... NOTE that must be radians... so don't dude to use degtorad() if you like degrees, while setting the uniforms.

Code:
//Shader Vertex

attribute vec3 in_Position;                  // (x,y,z)
attribute vec4 in_Colour;                    // (r,g,b,a)
attribute vec2 in_TextureCoord;              // (u,v)

varying vec3 v_vPos;
varying vec2 v_vTexcoord;
varying vec4 v_vColour;

uniform float posx;
uniform float posy;
uniform float posz;
uniform float cx;
uniform float cy;
uniform float cz;
uniform float rot_x;
uniform float rot_y;
uniform float rot_z;


mat4 rx = mat4( 1.0, 0.0, 0.0, 0.0,
                0.0,cos(rot_x),sin(rot_x), 0.0,
                0.0,-sin(rot_x),cos(rot_x), 0.0,
                0.0, 0.0, 0.0, 1.0);

mat4 ry = mat4( cos(rot_y),0.0, -sin(rot_y), 0.0,
                0.0, 1.0, 0.0, 0.0,
                sin(rot_y), 0.0, cos(rot_y), 0.0,
                0.0,0.0,0.0,1.0);
               
mat4 rz = mat4( cos(rot_z), sin(rot_z), 0.0, 0.0,
               -sin(rot_z), cos(rot_z), 0.0, 0.0,
               0.0        , 0.0       ,1.0 ,0.0,
               0.0        , 0.0       ,0.0 ,1.0);               


void main(){
    vec4 trans_pos = vec4(in_Position.xyz, 1.0);
    trans_pos.x += cx;
    trans_pos.y += cy;
    trans_pos.z += cz;
   
   
    gl_Position = gm_Matrices[MATRIX_WORLD_VIEW_PROJECTION] * rz * ry * rx * trans_pos;
   
    v_vColour = in_Colour;
    v_vTexcoord = in_TextureCoord;
}
 
I'd like to reiterate that I am fairly confident you can get buy using the built in world matrix. And if not that, it would be better to build your matrix in gml, rather than doing it in a shader. Since your transformations will be the same for every vertex, you're doing a lot of redundant math for each vertex, that could be done just once in gml instead.
 
Top