Javascript Three.js使用正交摄影机将2D映射到3D

Javascript Three.js使用正交摄影机将2D映射到3D,javascript,three.js,3d,Javascript,Three.js,3d,我有一个使用正交摄影机的3.js场景 this.camera = new THREE.OrthographicCamera(this.width / - 2, this.width / 2, this.height / 2, this.height / - 2, 1, 1000); this.camera.position.z = this.width / 2; this.scene.add(this.camera); 然后我有一个立方体(红色),我想定位在一些二维坐标(绿色)。我目前正在使用

我有一个使用正交摄影机的3.js场景

this.camera = new THREE.OrthographicCamera(this.width / - 2, this.width / 2, this.height / 2, this.height / - 2, 1, 1000);
this.camera.position.z = this.width / 2;
this.scene.add(this.camera);
然后我有一个立方体(红色),我想定位在一些二维坐标(绿色)。我目前正在使用此函数将二维坐标转换为三维坐标

from2Dto3D( position2d ) {
    var vector = new THREE.Vector3(),
        camera = this.camera,
        x = (position2d.x / this.width) * 2 - 1,
        y = (position2d.y / this.height) * 2 + 1;
    vector.set(x, y, 0.5);
    vector.unproject(this.camera);
    var direction = vector.sub(this.camera.position).normalize(),
        distance = - this.camera.position.z / direction.z,
        scaled = direction.multiplyScalar(distance),
        coords = this.camera.position.clone().add(scaled);
    return new THREE.Vector3(coords.x, coords.y, 0);
  }

如何将立方体精确定位在二维位置


事实证明,正交摄影机不需要此功能。我们只需要将屏幕系统坐标转换为3.js系统坐标。以下功能可用于:

convertCoords(x, y, z) {
        return {
            x: x - this.width / 2,
            y: -1*y + this.height / 2,
            z
        }
}

您需要显示更多的代码。我们如何知道问题不在于鼠标位置的计算

这里的代码应该可以工作,而不管摄影机方向如何,只要画布上没有应用css转换

      canvas.addEventListener('mousemove', (e) => {
        const rect = canvas.getBoundingClientRect();
        // get a canvas content pixel position
        const {width, height} = renderer.domElement;
        const canvasX = (e.clientX - rect.left) * width / rect.width;
        const canvasY = (e.clientY - rect.top) * height / rect.height;

        const clipX = (canvasX / width)  *  2 - 1;
        const clipY = (canvasY / height) * -2 + 1;

        // get the object's clip space Z
        const clipPos = new THREE.Vector3();
        mesh.getWorldPosition(clipPos);
        clipPos.project(camera);

        const pos = new THREE.Vector3(clipX, clipY, clipPos.z);
        pos.unproject(camera);
        mesh.position.copy(pos);
        render();
      });
函数main(){
const canvas=document.querySelector(“#c”);
const renderer=new THREE.WebGLRenderer({canvas});
常数大小=5;
常数近=5;
常数far=50;
常量摄影机=新的三个正交摄影机(-size,size,size,-size,near,far);
摄像机。位置。设置(5、7、12);
摄像机。注视(0,0,0);
const scene=new THREE.scene();
scene.background=新的三种颜色(“白色”);
constgridhelper=新的三个.gridHelper(10,10);
添加(gridHelper);
常数立方=1;
const cubeGeo=新的3.BoxBufferGeometry(cubeSize,cubeSize,cubeSize);
const cubeMat=新的3.MeshBasicMaterial({color:'red'});
常数网格=新的三个网格(cubeGeo,cubeMat);
场景。添加(网格);
函数resizeRenderToDisplaySize(渲染器){
const canvas=renderer.domeElement;
const width=canvas.clientWidth;
常数高度=canvas.clientHeight;
const needResize=canvas.width!==width | | canvas.height!==height;
如果(需要调整大小){
设置大小(宽度、高度、假);
}
返回需要调整大小;
}
函数render(){
if(ResizeRenderToDisplaySize(渲染器)){
const aspect=renderer.domElement.clientWidth/renderer.domElement.clientHeight;
camera.left=-size*aspect;
camera.right=尺寸*纵横比;
camera.updateProjectMatrix();
}
渲染器。渲染(场景、摄影机);
}
render();
canvas.addEventListener('mousemove',(e)=>{
const rect=canvas.getBoundingClientRect();
//获取画布内容像素位置
const{width,height}=renderer.domeElement;
const canvasX=(e.clientX-rect.left)*宽度/rect.width;
const canvasY=(e.clientY-rect.top)*高度/rect.height;
常数clipX=(画布/宽度)*2-1;
const clipY=(画布/高度)*-2+1;
//获取对象的剪辑空间Z
const clipPos=新的3.Vector3();
mesh.getWorldPosition(clipPos);
clipPos.项目(摄像机);
//注意:此代码在平面中移动对象
//摄影机的平面,而不是栅格的平面
const pos=新的三个向量3(clipX,clipY,clipPos.z);
位置未投影(摄像机);
网格位置复制(pos);
render();
});
window.addEventListener('resize',render);
}
main()
html,正文{
保证金:0;
身高:100%;
}
#c{
宽度:100%;
身高:100%;
显示:块;
}

事实并非如此。正交摄影机可以放置在任何位置并指向任何方向。此代码仅在非常特定的异常情况下工作
convertCoords(x, y, z) {
        return {
            x: x - this.width / 2,
            y: -1*y + this.height / 2,
            z
        }
}
      canvas.addEventListener('mousemove', (e) => {
        const rect = canvas.getBoundingClientRect();
        // get a canvas content pixel position
        const {width, height} = renderer.domElement;
        const canvasX = (e.clientX - rect.left) * width / rect.width;
        const canvasY = (e.clientY - rect.top) * height / rect.height;

        const clipX = (canvasX / width)  *  2 - 1;
        const clipY = (canvasY / height) * -2 + 1;

        // get the object's clip space Z
        const clipPos = new THREE.Vector3();
        mesh.getWorldPosition(clipPos);
        clipPos.project(camera);

        const pos = new THREE.Vector3(clipX, clipY, clipPos.z);
        pos.unproject(camera);
        mesh.position.copy(pos);
        render();
      });