关于three.js中的矩阵更新

1. 概述

使用如下代码绘制一个面:

'use strict';

function init() {
    //console.log("Using Three.js version: " + THREE.REVISION);   

    // create a scene, that will hold all our elements such as objects, cameras and lights.
    var scene = new THREE.Scene();

    // create a camera, which defines where we're looking at.
    var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);

    // position and point the camera to the center of the scene
    camera.position.set(0, 0, 100);   //相机的位置
    camera.up.set(0, 1, 0);         //相机以哪个方向为上方
    camera.lookAt(new THREE.Vector3(1, 2, 3));          //相机看向哪个坐标。

    console.log(camera.matrixWorldInverse);
 
    // create a render and set the size
    var renderer = new THREE.WebGLRenderer();
    renderer.setClearColor(new THREE.Color(0x000000));
    renderer.setSize(window.innerWidth, window.innerHeight);

    // add the output of the renderer to the html element
    document.getElementById("webgl-output").appendChild(renderer.domElement);

    
    // create the ground plane
    var planeGeometry = new THREE.PlaneGeometry(60, 20);
    var planeMaterial = new THREE.MeshBasicMaterial({
        color: 0xAAAAAA
    });

    var plane = new THREE.Mesh(planeGeometry, planeMaterial);

    // add the plane to the scene
    scene.add(plane);

    // rotate and position the plane    
    plane.position.set(15, 8, -10);
    plane.rotation.x = THREE.Math.degToRad(30);
    plane.rotation.y = THREE.Math.degToRad(45);
    plane.rotation.z = THREE.Math.degToRad(60);

    console.log(plane.matrixWorld);
 
    renderer.render(scene, camera);
}

打印输出的视图矩阵和模型矩阵如下:
imglink1

而去掉最后的渲染语句:

renderer.render(scene, camera);

之后,打印输出的视图矩阵和模型矩阵如下:
imglink2

可以发现两者的输出结果并不一致,这其实涉及到three.js中矩阵更新的问题。

2. 详解

three.js中的Mesh和Camera都继承自Object3D,Object3D提供了更新图形矩阵的接口:
imglink3

在分别设置Mesh和camera的图形变换参数之后,需要调用updateMatrixWorld()才能保证图形矩阵正确:

camera.updateMatrixWorld(true);
plane.updateMatrixWorld(true);

但是在调用renderer.render之后,three.js就会使得矩阵自动进行更新。所以除非必要,模型矩阵和视图矩阵可以不用显示更新。而console.log是异步操作,所以会出现打印信息是正常的现象。如果是单步调式模式,如果不调用updateMatrixWorld(),显示的就会是初始化的矩阵信息。

除此之外,Camera的投影矩阵也值得注意。PerspectiveCamera提供了更新投影矩阵的接口:
imglink4
文档很明确的说明了,在改变Camera的投影参数之后,必须调用一次updateProjectionMatrix才能使Camera的效果生效。

posted @ 2020-05-31 17:00  charlee44  阅读(2056)  评论(0编辑  收藏  举报