ThreeJS中的GL_PROJECTION和GL_MODELVIEW

时间:2017-09-19 21:57:23

标签: three.js

我试图将一些传统的OpenGL 1.x代码移植到WebGL / Three.JS:

glMatrixMode(GL_PROJECTION);
glLoadMatrixf(...)
glMatrixMode(GL_MODELVIEW);
glLoadMatrixf(...)
// rest of rendering

我正在设置我的Three.JS相机的投影(注意我不想使用PerspectiveCamera,我的投影矩阵是预先计算的):

var camera = new THREE.Camera()
camera.projectionMatrix.fromArray(...)

我正在设置我的Three.JS相机的姿势:

var mat = new THREE.Matrix4();
mat.fromArray(...);
mat.decompose(camera.position, camera.quaternion, camera.scale);
camera.updateMatrix();
scene.updateMatrixWorld(true);

我正在测试以下内容:

var geometry = new THREE.SphereGeometry(10, 35, 35);
var material = new THREE.MeshLambertMaterial({color: 0xffff00});
mesh = new THREE.Mesh(geometry, material);
camera.add(mesh);
mesh.position.set(0, 0, -40); // fix in front of the camera
scene.add(mesh);

我可以看到我的相机姿势设置正确(通过记录),但没有任何内容呈现在屏幕上。我是否错误地设置了投影矩阵?

2 个答案:

答案 0 :(得分:0)

您确定投影矩阵是否正确? (正如Sepehr Well指出的那样,你是否正在将相机添加到场景中?)

在相机代码中调用updateProjectionMatrix有一些地方会覆盖你的矩阵,所以我在那里放一个断点来看看它是否正在这样做。

答案 1 :(得分:0)

该问题原来是我的modelView矩阵。这就是我将遗留代码移植到ThreeJS的方式:

// OpenGL 1.x code
glMatrixMode(GL_PROJECTION);
glLoadMatrixf(projectionMatrix)
glMatrixMode(GL_MODELVIEW);
glLoadMatrixf(modelViewMatrix)

// ThreeJS code
/* GL_PROJECTION matrix can be directly applied here */
camera = new THREE.Camera()
camera.projectionMatrix.copy(projectionMatrix)

/* GL_MODELVIEW should be inverted first */
modelViewMatrix.getInverse(modelViewMatrix)
modelViewMatrix.decompose(camera.position, camera.quaternion, camera.scale)

关注ThreeJS WebGL renderer source,ThreeJS' modelViewMatrix是通过将相机的matrixWorldInverse乘以对象的矩阵来计算的。

Matrix4' decompose更新了相机的matrixWorld,因此模型视图计算中使用的实际矩阵最终会被反转。

编辑:这里是即插即用的ThreeJS相机,可用于此场景:

/**
 * @author Sepehr Laal
 * @file OpenGLCamera.js
 */

function OpenGLCamera () {

  THREE.Camera.call(this)

  this.type = 'OpenGLCamera'
}

OpenGLCamera.prototype = Object.assign(Object.create(THREE.Camera.prototype), {

  constructor: OpenGLCamera,

  isOpenGLCamera: true,

  /*
   * Equivalent to OpenGL 1.x:
   * glMatrixMode(GL_PROJECTION);
   * glLoadMatrixf(...)
   */
  setProjectionFromArray: function (arr) {

    this.projectionMatrix.fromArray(arr)

  },

  /*
   * Equivalent to OpenGL 1.x:
   * glMatrixMode(GL_MODELVIEW);
   * glLoadMatrixf(...)
   */
  setModelViewFromArray: function () {

    var m = new THREE.Matrix4();

    return function (arr) {
      m.fromArray(arr)
      m.getInverse(m)
      m.decompose(this.position, this.quaternion, this.scale)
    };

  }()

})