将 Point3D 转换为 Screen2D 在 three.js 中得到错误的结果
convert Point3D To Screen2D get wrong result in three.js
我在 three.js 69
中使用了这样的函数
function Point3DToScreen2D(point3D,camera){
var p = point3D.clone();
var vector = p.project(camera);
vector.x = (vector.x + 1) / 2 * window.innerWidth;
vector.y = -(vector.y - 1) / 2 * window.innerHeight;
return vector;
}
当我保持场景静止时效果很好。
但是当我旋转场景时它犯了一个错误并且 return 在屏幕中的位置错误。 当我旋转大约 180 度时会发生这种情况 degrees.It 在屏幕中应该没有位置但是它显示。
我在update
中设置了一个位置var tmpV=Point3DToScreen2D(new THREE.Vector3(-67,1033,-2500),camera);
并用css3d.And显示,当我旋转180度但小于360度时,该点显示在屏幕上again.Obviously 从现场可以看出位置不对,我没有旋转360度
我对 Matrix
知之甚少,所以我不知道 project
是如何工作的。
这里是 three.js 中 project
的来源:
project: function () {
var matrix;
return function ( camera ) {
if ( matrix === undefined ) matrix = new THREE.Matrix4();
matrix.multiplyMatrices( camera.projectionMatrix, matrix.getInverse( camera.matrixWorld ) );
return this.applyProjection( matrix );
};
}()
matrix.getInverse( camera.matrixWorld )
是多余的吗?我试图删除它,但没有用。
谁能帮帮我?谢谢。
您正在使用如下模式将 3D 点从世界 space 投影到屏幕 space:
var vector = new THREE.Vector3();
var canvas = renderer.domElement;
vector.set( 1, 2, 3 );
// map to normalized device coordinate (NDC) space
vector.project( camera );
// map to 2D screen space
vector.x = Math.round( ( vector.x + 1 ) * canvas.width / 2 ),
vector.y = Math.round( ( - vector.y + 1 ) * canvas.height / 2 );
vector.z = 0;
但是,使用这种方法,相机后面的点也会投影到屏幕上 space。
你说你想过滤掉相机后面的点。为此,您可以先使用此模式:
var matrix = new THREE.Matrix4(); // create once and reuse
...
// get the matrix that maps from world space to camera space
matrix.getInverse( camera.matrixWorld );
// transform your point from world space to camera space
p.applyMatrix( matrix );
由于摄像机位于摄像机 space 的原点,并且由于摄像机始终向下看摄像机 space 的负 z 轴,摄像机后面的点将具有 z -坐标大于零。
// check if point is behind the camera
if ( p.z > 0 ) ...
three.js r.71
和上面的例子一样,但是你可以检查vector.z来确定它是否在前面。
var vector = new THREE.Vector3();
var canvas = renderer.domElement;
vector.set( 1, 2, 3 );
// map to normalized device coordinate (NDC) space
vector.project( camera );
// map to 2D screen space
vector.x = Math.round( ( vector.x + 1 ) * canvas.width / 2 ),
vector.y = Math.round( ( - vector.y + 1 ) * canvas.height / 2 );
//behind the camera if z isn't in 0..1 [frustrum range]
if(vector.z > 1){
vector = null;
}
要更深入地研究这个答案:
// behind the camera if z isn't in 0..1 [frustrum range]
if(vector.z > 1){
vector = null;
}
This is not true. The mapping is not continuous. Points beyond the far
plane also map to z-values greater than 1
投影矢量的 z 值究竟代表什么? X 和 Y 在归一化裁剪空间 [-1,1] 中,那么 z?
这是真的吗?
projectVector.project(camera);
var inFrontOfCamera = projectVector.z < 1;
由于摄像机位于摄像机 space 的原点,并且由于摄像机始终向下看摄像机 space 的负 z 轴,摄像机后面的点将具有 z -坐标大于1.
//check if point is behind the camera
if ( p.z > 1 ) ...
注意:如果满足此条件,则投影坐标需要中心对称
{x: 0.233, y: -0.566, z: 1.388}
// after transform
{x: -0.233, y: 0.566, z: 1.388}
我在 three.js 69
中使用了这样的函数 function Point3DToScreen2D(point3D,camera){
var p = point3D.clone();
var vector = p.project(camera);
vector.x = (vector.x + 1) / 2 * window.innerWidth;
vector.y = -(vector.y - 1) / 2 * window.innerHeight;
return vector;
}
当我保持场景静止时效果很好。 但是当我旋转场景时它犯了一个错误并且 return 在屏幕中的位置错误。 当我旋转大约 180 度时会发生这种情况 degrees.It 在屏幕中应该没有位置但是它显示。
我在update
中设置了一个位置var tmpV=Point3DToScreen2D(new THREE.Vector3(-67,1033,-2500),camera);
并用css3d.And显示,当我旋转180度但小于360度时,该点显示在屏幕上again.Obviously 从现场可以看出位置不对,我没有旋转360度
我对 Matrix
知之甚少,所以我不知道 project
是如何工作的。
这里是 three.js 中 project
的来源:
project: function () {
var matrix;
return function ( camera ) {
if ( matrix === undefined ) matrix = new THREE.Matrix4();
matrix.multiplyMatrices( camera.projectionMatrix, matrix.getInverse( camera.matrixWorld ) );
return this.applyProjection( matrix );
};
}()
matrix.getInverse( camera.matrixWorld )
是多余的吗?我试图删除它,但没有用。
谁能帮帮我?谢谢。
您正在使用如下模式将 3D 点从世界 space 投影到屏幕 space:
var vector = new THREE.Vector3();
var canvas = renderer.domElement;
vector.set( 1, 2, 3 );
// map to normalized device coordinate (NDC) space
vector.project( camera );
// map to 2D screen space
vector.x = Math.round( ( vector.x + 1 ) * canvas.width / 2 ),
vector.y = Math.round( ( - vector.y + 1 ) * canvas.height / 2 );
vector.z = 0;
但是,使用这种方法,相机后面的点也会投影到屏幕上 space。
你说你想过滤掉相机后面的点。为此,您可以先使用此模式:
var matrix = new THREE.Matrix4(); // create once and reuse
...
// get the matrix that maps from world space to camera space
matrix.getInverse( camera.matrixWorld );
// transform your point from world space to camera space
p.applyMatrix( matrix );
由于摄像机位于摄像机 space 的原点,并且由于摄像机始终向下看摄像机 space 的负 z 轴,摄像机后面的点将具有 z -坐标大于零。
// check if point is behind the camera
if ( p.z > 0 ) ...
three.js r.71
和上面的例子一样,但是你可以检查vector.z来确定它是否在前面。
var vector = new THREE.Vector3();
var canvas = renderer.domElement;
vector.set( 1, 2, 3 );
// map to normalized device coordinate (NDC) space
vector.project( camera );
// map to 2D screen space
vector.x = Math.round( ( vector.x + 1 ) * canvas.width / 2 ),
vector.y = Math.round( ( - vector.y + 1 ) * canvas.height / 2 );
//behind the camera if z isn't in 0..1 [frustrum range]
if(vector.z > 1){
vector = null;
}
要更深入地研究这个答案:
// behind the camera if z isn't in 0..1 [frustrum range]
if(vector.z > 1){
vector = null;
}
This is not true. The mapping is not continuous. Points beyond the far plane also map to z-values greater than 1
投影矢量的 z 值究竟代表什么? X 和 Y 在归一化裁剪空间 [-1,1] 中,那么 z?
这是真的吗?
projectVector.project(camera);
var inFrontOfCamera = projectVector.z < 1;
由于摄像机位于摄像机 space 的原点,并且由于摄像机始终向下看摄像机 space 的负 z 轴,摄像机后面的点将具有 z -坐标大于1.
//check if point is behind the camera
if ( p.z > 1 ) ...
注意:如果满足此条件,则投影坐标需要中心对称
{x: 0.233, y: -0.566, z: 1.388}
// after transform
{x: -0.233, y: 0.566, z: 1.388}