3.JS:从3D透视场景转换为2D拼字法HUD场景



我在3D场景中具有对象(很远),使用透视摄像头和使用拼字摄像头设置的2D HUD:

this.scene = new THREE.Scene();
this.hud = new THREE.Scene();
this.camera = new THREE.PerspectiveCamera( 30, aspect, front, back );
this.camera.position.set(0,0,0);
this.hudCamera = new THREE.OrthographicCamera (-this.windowHalfX,this.windowHalfX, this.windowHalfY, -this.windowHalfY, 1, 10);
this.hudCamera.position.set(0,0,10);

这是我的渲染循环:

  updateFrame : function () {
    this.renderer.clear();
    this.renderer.render( this.scene, this.camera );
    this.renderer.clearDepth();
    this.renderer.render( this.hud, this.hudCamera );
  },

如何使用它们在3D场景中的位置找到对象在HUD中的位置?

为了找到3D对象的2D HUD位置(使用Trix.js版本R71),您可以执行以下操作,我从这篇文章中进行了修改:

  findHUDPosition : function (obj) {
      var vector = new THREE.Vector3();
      obj.updateMatrixWorld();
      vector.setFromMatrixPosition(obj.matrixWorld);
      vector.project(this.camera);
      vector.x = ( vector.x * this.windowHalfX );
      vector.y = ( vector.y * this.windowHalfY );
      return {
          x: vector.x,
          y: vector.y,
          z: vector.z
      }
  }

参数obj是您试图在HUD中找到位置的对象。

vector.project(this.camera);通过相机的near平面从对象到this.camera的位置绘制向量。

vector的组件的新值是投影矢量和this.camera的相交。

不过,坐标位于三分。JS的世界坐标系统中,因此我们必须快速转换到像素坐标,以扩展到我们的画布的大小。

  vector.x = ( vector.x * this.windowHalfX );
  vector.y = ( vector.y * this.windowHalfY );

上面的转换是用于设置,其中HUD坐标系在屏幕中心的原点(0,0),最大值为一半的画布分辨率。例如,如果您的画布为1024 x 768像素,则右上角的位置为(512,384)。

对于典型的屏幕坐标系,右下角为(1024,768),屏幕的中间为(512,384)。要拥有此设置,您可以使用以下转换,如本文所示。

    vector.x = ( vector.x * widthHalf ) + widthHalf;
    vector.y = - ( vector.y * heightHalf ) + heightHalf;

注意,z坐标现在没关系,因为我们在2d。

您要做的最后一件事是确保您在2D中显示的对象实际上可以看到透视摄像机。这很简单,就像检查对象是否属于this.camera的frustum一样简单。遵循代码的来源

checkFrustrum : function (obj) {
    var frustum = new THREE.Frustum();
    var projScreenMatrix = new THREE.Matrix4();
    this.camera.updateMatrix();
    this.camera.updateMatrixWorld();
    projScreenMatrix.multiplyMatrices( this.camera.projectionMatrix, this.camera.matrixWorldInverse );
    frustum.setFromMatrix( new THREE.Matrix4().multiplyMatrices( this.camera.projectionMatrix,
                                                     this.camera.matrixWorldInverse ) );
    return frustum.containsPoint ( obj.position );
}

如果没有这样做,则可以具有在2D场景中可见的相机后面注册的对象(这构成了对象跟踪的问题)。更新obj的矩阵和矩阵世界也是很好的做法。

相关内容

  • 没有找到相关文章

最新更新