2015-05-01 112 views
1

我有对象(很远的地方)在三维场景,使用透视相机和2D HUD设置使用正交相机:three.js所:从三维视角场景转换到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); 
    }, 

我如何才能找到在HUD对象的位置,使用在3D场景中的位置?

+0

你的问题没有任何意义,因为你的正交相机参数是以像素为单位。阅读http://stackoverflow.com/questions/17558085/three-js-orthographic-camera/17567292#17567292。 – WestLangley

+0

我已经意识到这一点。我有一个解决方案,我会立即发布。 – Boogiechillin

回答

2

为了找到一个3D对象的2D HUD位置(使用three.js所版本R71),可以执行以下操作,这是我从this post改性:

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的近平面的交点。

尽管坐标是在three.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)。要进行此设置,可以使用以下转换,如this post中所示。

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

请注意,现在z坐标并不重要,因为我们在2D中。

您要做的最后一件事是确保您以2D显示的对象实际上对透视摄影机可见。这与查看对象是否落在this.camera的平截头体内一样简单。 source for following code

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的矩阵和矩阵世界也是很好的做法。