美文网首页
threejs 中模型旋转实现原理和更新流程

threejs 中模型旋转实现原理和更新流程

作者: BitMonkey | 来源:发表于2024-05-16 10:07 被阅读0次

在项目上,我们会通过设置 Mesh 上的rotation 属性来实现模型旋转的控制,那其中threejs 是怎么实现的呢?

调用 mesh.rotation 属性实现旋转

通过 Object3D 源码可以知道, rotation 其实是代理了 Euler 实例,当我们设置object.rotation.x , 其实调用的是 euler.x 设置。些时在 Object3D 中注册了一个变更回调,在更新了x值后会执行回调,在回调中会更新 Object3D 上的四元数计算旋转值。

image.png

在回调中他没有立马去更新 模型的 matrixWorld。当下次渲染函数执行的时候才会触发更新,更新流程如下

  1. 当执行renderer.render 的时候,会调用scene.updateMatrixWorld 方法,通过updatematrixWorld 方法会调用 updateMatrix。 在updatematrixWorld 方法中会递归调用子节点的此方法。从而更新模型 的matrixWorld.
    updateMatrix() {
              // 实现与四元数的结合
        this.matrix.compose( this.position, this.quaternion, this.scale );

        this.matrixWorldNeedsUpdate = true;

    }

    updateMatrixWorld( force ) {

        if ( this.matrixAutoUpdate ) this.updateMatrix();

        if ( this.matrixWorldNeedsUpdate || force ) {

            if ( this.parent === null ) {

                this.matrixWorld.copy( this.matrix );

            } else {
                              // 更新 matrixWorld
                this.matrixWorld.multiplyMatrices( this.parent.matrixWorld, this.matrix );

            }

            this.matrixWorldNeedsUpdate = false;

            force = true;

        }

        // update children

        const children = this.children;

        for ( let i = 0, l = children.length; i < l; i ++ ) {

            const child = children[ i ];

            if ( child.matrixWorldAutoUpdate === true || force === true ) {

                child.updateMatrixWorld( force );

            }

        }

    }

在真实渲染模型 的时候,会在renderer.renderObject 方法中计算模型 的modelViewMatrix,这个矩阵就是着色器用来计算模型旋转后位置 的矩阵。从而实现旋转

        function renderObject( object, scene, camera, geometry, material, group ) {

            object.onBeforeRender( _this, scene, camera, geometry, material, group );
                        // 计算 modelViewMatrix
            object.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, object.matrixWorld );
            object.normalMatrix.getNormalMatrix( object.modelViewMatrix );

            material.onBeforeRender( _this, scene, camera, geometry, object, group );

            if ( material.transparent === true && material.side === DoubleSide && material.forceSinglePass === false ) {

                material.side = BackSide;
                material.needsUpdate = true;
                _this.renderBufferDirect( camera, scene, geometry, material, object, group );

                material.side = FrontSide;
                material.needsUpdate = true;
                _this.renderBufferDirect( camera, scene, geometry, material, object, group );

                material.side = DoubleSide;

            } else {

                _this.renderBufferDirect( camera, scene, geometry, material, object, group );

            }

            object.onAfterRender( _this, scene, camera, geometry, material, group );

        }

相关文章

网友评论

      本文标题:threejs 中模型旋转实现原理和更新流程

      本文链接:https://www.haomeiwen.com/subject/kfbbfjtx.html