Shear doesn't produce the expected effect

I’m trying to understand, by constructing an example, how shearing works in three.js.

My problem is that the example I’ve made doesn’t behave as I would expect.

I’m using the notation of the three.js Matrix4 documentation:
xy - the amount to shear X by Y.
xz - the amount to shear X by Z.
yx - the amount to shear Y by X.
yz - the amount to shear Y by Z.
zx - the amount to shear Z by X.
zy - the amount to shear Z by Y.

The example creates a unit cube with one vertex at the origin. The gui allows user to make adjustments to the xy, xz etc shear values of the matrix

 const shearMatrix = new THREE.Matrix4();

Setting xy=1 and clicking reportShearMatrix logs to the console that I’ve succeeded in constructing a matrix

1 0 0 0
1 1 0 0
0 0 1 0
0 0 0 1

with the shear of X by Y =1

I’d expect the result of the i unit vector, here with the homogeneous coordinate w=1 added, transformed by that shear to be

| 1 0 0 0 |    | 1 |   | 1 |
| 1 1 0 0 | x  | 0 | = | 1 |
| 0 0 1 0 |    | 0 |   | 0 |
| 0 0 0 1 |    | 1 |   | 1 |

I can test that, by next clicking on applyShear and looking at the vertex positions of the transformed cube.


However, it doesn’t produce the effect I’d expect.

For example, here is the unit cube before and after the shear defined by the matrix above.

unit-cube-before-shear unit-cube-after-attempted-shear

Visually, the (1,0,0,1) vector hasn’t been transformed to (1,1,0,1).

Could anyone enlighten me as to my error here?

if you look at how cube.applyMatrix4 works, you will see that shear is removed.

You need to turn matrix auto updates off and set the matrix manually.


Thank you @makc3d

That looks as I was expecting, here is before & after the shear.

unit-cube-before-shear-fixed unit-cube-after-shear-fixed

As a newbie, it seems odd that of the various transformations, shear is treated differently. Maybe it will fall into place as I get to know the library.

it is odd because you expect cube.matrix to be a 1st class public property, but it is not - it is calculated from cube.position, cube.quaternion and cube.scale unless you tell it not to.

then, decompose is doing its best to restore position/quaternion/scale from the matrix you calculate, but with shear it just cant.

1 Like