It took me a bit to get my head around matrix transformation as well, so here’s an example to help you out. I can’t find one of the sites I used to help me learn how to make a rotation matrix by hand but I posted a couple links below. The first seems build the exact matrix I made below.

Here is the modified vertex shader of standard phong exported shader. It has a couple of transformations. First function that creates a rotation matrix is declared. Then another function that makes a 4x4 transformation matrix is declared ( that also uses the first function).

Then two variables are created each of which calls one of the matrix functions. One is a mat4 which is used to translate, scale and rotate the object. The second is mat3 which do another rotation after the first transform.

Notice the two matrices are made outside of the main() function. The matrices are only created once for the object, not for every point. If you want to use them and input different values based on point or instance id’s then they’ll need to be created within the main() function.

[code]uniform vec3 uTranslate;

uniform vec3 uScale;

uniform vec3 uRotate;

uniform vec3 uRotate2;

out Vertex {

vec4 color;

vec3 camSpaceVert;

vec3 camVector;

vec3 norm;

}vVert;

// Return rotation matrix

mat3 rotationMatrixXYZ(vec3 r)

{

float cx = cos(radians(r.x));

float sx = sin(radians(r.x));

float cy = cos(radians(r.y));

float sy = sin(radians(r.y));

float cz = cos(radians(r.z));

float sz = sin(radians(r.z));

```
return mat3(cy * cz, cx * sz + sx * sy * cz, sx * sz - cx * sy * cz,
-cy * sz, cx * cz - sx * sy * sz, sx * cz + cx * sy * sz,
sy, -sx * cy, cx * cy);
```

}

//return transformation matrix

mat4 xFormXYZ(vec3 t, vec3 sc, vec3 r)

{

mat3 scale = mat3( sc.x, 0.0, 0.0,

0.0, sc.y, 0.0,

0.0, 0.0, sc.z);

```
mat3 xfm = rotationMatrixXYZ(uRotate) * scale;
return mat4(xfm[0][0], xfm[0][1], xfm[0][2], 0.0,
xfm[1][0], xfm[1][1], xfm[1][2], 0.0,
xfm[2][0], xfm[2][1], xfm[2][2], 0.0,
t.x, t.y, t.z, 1.0 );
```

/* this would be valid as well

return mat4(xfm[0], 0.0,

xfm[1], 0.0,

xfm[2], 0.0,

t, 1.0 );

*/

}

mat4 xfm = xFormXYZ(uTranslate, uScale, uRotate);

mat3 rot2 = rotationMatrixXYZ(uRotate2);

void main()

{

```
//multilply the point by the transform matrix, it must be a vec4 because the matrix is 4x4 matrix and includes translation
vec4 point = xfm * vec4(P, 1.0);
//the normal needs to be rotated also but not translated so the w component is 0.0
vec3 normal = (xfm * vec4(N, 0.0)).xyz;
//do another rotation after first transformation - just need vec3's this time becuase the rotation matrix is 3x3
point.xyz = rot2 * point.xyz;
normal = rot2 * normal;
// First deform the vertex and normal
// TDDeform always returns values in world space
vec4 worldSpaceVert =TDDeform(point);
vec4 camSpaceVert = uTDMat.cam * worldSpaceVert;
gl_Position = TDCamToProj(camSpaceVert);
// This is here to ensure we only execute lighting etc. code
// when we need it. If picking is active we don't need this, so
// this entire block of code will be ommited from the compile.
// The TD_PICKING_ACTIVE define will be set automatically when
// picking is active.
```

#ifndef TD_PICKING_ACTIVE

```
vec3 camSpaceNorm = uTDMat.camForNormals * TDDeformNorm(normal).xyz;
vVert.norm.stp = camSpaceNorm.stp;
vVert.camSpaceVert.xyz = camSpaceVert.xyz;
vVert.color = TDInstanceColor(Cd);
vec3 camVec = -camSpaceVert.xyz;
vVert.camVector.stp = camVec.stp;
```

#else // TD_PICKING_ACTIVE

```
// This will automatically write out the nessesarily values
// for this shader to work with picking.
// See the documentation if you want to write custom values for picking.
TDWritePickingValues();
```

#endif // TD_PICKING_ACTIVE

}

[/code]

engineering.purdue.edu/~bethel/rot2.pdf

fastgraph.com/makegames/3drotation/

cheers

Keith

Transform matrix example.toe (7.73 KB)