Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Matrices in Three.js #1188

Closed
zz85 opened this issue Jan 26, 2012 · 4 comments
Closed

Matrices in Three.js #1188

zz85 opened this issue Jan 26, 2012 · 4 comments
Labels

Comments

@zz85
Copy link
Contributor

zz85 commented Jan 26, 2012

I'm trying to demystify how matrices are used in three.js and after looking at source code and other issues explanations, I'm nevertheless confused :S

From my understanding, three.js's WebGLRenderer would pass several matrices to WebGL, of which the minimal is

  • projectionMatrix
  • modelViewMatrix

projection matrix takes care of the the camera's aspect ratio, fov, front and back. model view matrix takes care of where an object are is relatively in space. therefore I'm guessing to render any object projected to a 2d canvas, one could do projectionMatrix * modelviewMatrix.

the question is perhaps, from where do three.js get the matrices from?

  • projectionMatrix from camera?
  • modelViewMatrix from object3D?

if we inspect objects in three.js scene, there are a bunch of matrices in them like matrix, matrixWorld, matrixRotationWorld etc...

so I tried playing with something like object.matrix.getPosition() and object.matrixWorld.getPosition() but it seems all I get is some values which doesn't make sense. if I do object.matrix.extractPosition() instead, I'll get an error TypeError: Cannot read property 'n14' of undefined

so apparently i'm using them incorrectly, or that i've a bad understanding of how the matrices work in three.js. would anyone care to enlighten this noob again? :cI

@alteredq
Copy link
Contributor

JS matrices

// local transform (object space)
// composed from position / rotation / scale
// object.updateMatrix() must be called for this to be correct
object.matrix             

// global transform (world space)
// scene graph must be updated for this to be correct
// scene.updateMatrixWorld()
object.matrixWorld       

// just rotation part of global transform, 
// computed on demand in Ray / Projector
// otherwise not used
object.matrixRotationWorld 

Positions in JS

localPosition = object.position;
worldPosition = object.matrixWorld.getPosition();

JS matrices => GLSL uniforms

object.matrixWorld => objectMatrix // till r49
object.matrixWorld => modelMatrix // since r50
camera.projectionMatrix => projectionMatrix
camera.matrixWorldInverse => viewMatrix
camera.matrixWorldInverse * object.matrixWorld => modelViewMatrix 

JS buffer => GLSL attribute

geometry.vertices[ i ].position => position

GLSL full transform

gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );

Alternatively

gl_Position = projectionMatrix * viewMatrix * objectMatrix * vec4( position, 1.0 ); // till r49
gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4( position, 1.0 ); // since r50

@axhm3a
Copy link

axhm3a commented Jan 26, 2012

thanks for the question,
thanks for the answer,

exactly what i needed!

@zz85
Copy link
Contributor Author

zz85 commented Jan 26, 2012

crystal clear again, thanks @alteredq ! :)

also, i realized that its probably not a good idea to use object.matrixWorld.getPosition() outside the render loop. i dug into Matrix4 and the code for getPosition() is

    return THREE.Matrix4.__v1.set( this.n14, this.n24, this.n34 );

which is pointing to a common vector with Matrix. this means that every time a render() call is made, the values are probably going to be overwritten. a good way to keep a copy of the object world position would be to do

    var mw = object.matrixWorld;
    var position = new THREE.Vector3(mw.n14, mw.n24, mw.n34 );

will link this page to the FAQ too! :)

(edit: or simply do a object.matrixWorld.getPosition().clone())

@zz85 zz85 closed this as completed Jan 26, 2012
@alteredq
Copy link
Contributor

this means that every time a render() call is made, the values are probably going to be overwritten. a good way to keep a copy of the object world position would be to do

http://mrdoob.github.com/three.js/docs/48/api/core/Matrix4.html#Matrix4.getPosition

Indeed ;)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants