I found examples on how to create (axonometric) isometric camera in Isometric camera with THREE.js, but how can I create an axonometric oblique?
-
2Are you willing to accept a work-around hack in which the geometry of your mesh is skewed with a shear matrix before rendering, as in [this fiddle](http://jsfiddle.net/8ko9x81n/)? – WestLangley Sep 24 '14 at 18:33
-
Yes, this is a good work-around, thanks – lupok Sep 26 '14 at 10:18
-
Excellent. I posted an answer documenting the approach. – WestLangley Sep 26 '14 at 12:54
2 Answers
You can render a scene with an oblique cabinet perspective using a work-around in which the camera is an orthographic one, and the geometry of your mesh is skewed with a shear matrix prior to rendering.
// create shear matrix
var alpha = Math.PI / 6; // or Math.PI / 4
var Syx = 0,
Szx = - 0.5 * Math.cos( alpha ),
Sxy = 0,
Szy = - 0.5 * Math.sin( alpha ),
Sxz = 0,
Syz = 0;
var matrix = new THREE.Matrix4();
matrix.set( 1, Syx, Szx, 0,
Sxy, 1, Szy, 0,
Sxz, Syz, 1, 0,
0, 0, 0, 1 );
// apply shear matrix to geometry
mesh.geometry.applyMatrix4( matrix ); // this is the work-around
EDIT: You can alternatively use the method Matrix4.makeShear()
to populate a shear matrix.
three.js r.144

- 102,557
- 10
- 276
- 276
-
This breaks unfortunately for the `THREE.BoxGeometry` the `scale.z` option, e.g. `box.scale.z = 5` is without any effect, thus you can't change the `depth` of a BoxGeometry anymore. Do you have any idea to fix that? – Marc J. Schmidt Dec 03 '19 at 21:05
-
Prior to applying the shear matrix, you can do this: `mesh.geometry.scale( 1, 1, 2 );` Equivalently, multiply the elements of the third column of the shear matrix by 2. – WestLangley Dec 03 '19 at 21:47
-
Yes, prior to applyMatrix I could also use the regular constructor arguments since it will be newly created anyways, but that's what I wanted to avoid. I only use `scale.z.` to change the `depth` of the box after it has been created because in BoxGeometry.constructor's `depth` can't be changed afterwards. I guess I have to keep destroying and recreating it when its depth should change. – Marc J. Schmidt Dec 03 '19 at 21:52
Based on @WestLangley's code, here's how you can do an oblique projection without modifying the geometry, just the camera's matrix.
// shear matrix
// ref: http://www.flipcode.com/documents/matrfaq.html#Q43
// | 1 Syx Szx 0 |
// | |
// | Sxy 1 Szy 0 |
// M = | |
// | Sxz Syz 1 0 |
// | |
// | 0 0 0 1 |
// | |
var alpha = Math.PI / 6; // or Math.PI / 4
var Syx = 0,
Szx = - 0.5 * Math.cos( alpha ),
Sxy = 0,
Szy = - 0.5 * Math.sin( alpha ),
Sxz = 0,
Syz = 0;
var matrix = new THREE.Matrix4();
matrix.set( 1, Syx, Szx, 0,
Sxy, 1, Szy, 0,
Sxz, Syz, 1, 0,
0, 0, 0, 1 );
// apply shear matrix to camera
camera.projectionMatrix.multiply(matrix);
camera.projectionMatrixInverse.getInverse( camera.projectionMatrix );
You would make these projectionMatrix
modifications after calling camera.updateProjectionMatrix()
. I looked inside the code of camera.updateProjectionMatrix
to figure out how to do this, including learning of the inverse matrix that it stores.
One slight downside to this is it moves the view somewhat, but you can just move the camera position or frustum boundaries to account for that. (Maybe there's a better way.)
three.js r.120

- 3,714
- 2
- 29
- 30