threejs 屏幕空间转世界空间

目前有不少博客里都有介绍转换方法,并且方法都是大同小异的,这里参考的是这篇博客

这里想记录的也不是转换方法,想记录下一个容易犯的误区。正常情况下说到坐标转换都是一个点转换成另一个点,但是从屏幕空间转世界空间我感觉更应该理解为从摄像机的位置向屏幕上的点发出一条射线,此射线非RayCast,只是带方向的线。

	screenToWorld(event) {
    const x = event.clientX;//鼠标单击坐标X
    const y = event.clientY;//鼠标单击坐标Y
    // 屏幕坐标转标准设备坐标
    const x1 = (x / window.innerWidth) * 2 - 1;
    const y1 = -(y / window.innerHeight) * 2 + 1;
    //标准设备坐标(z=0.5这个值并没有一个具体的说法)
    const stdVector = new Vector3(x1, y1, 0.5);

    const worldVector = stdVector.unproject(this.defaultCamera);
  }

一开始用这个转换方法时就想在得到的结果上生成一个球,看是否正确的,结果啥也看不到。
后面猜想是不是距离相机太近(比近平面还近),然后稍微修改了下代码,结果也确实是这样的

screenToWorld(event) {
    const x = event.clientX;//鼠标单击坐标X
    const y = event.clientY;//鼠标单击坐标Y
    // 屏幕坐标转标准设备坐标
    const x1 = (x / window.innerWidth) * 2 - 1;
    const y1 = -(y / window.innerHeight) * 2 + 1;
    //标准设备坐标(z=0.5这个值并没有一个具体的说法)
    const stdVector = new Vector3(x1, y1, 0.5);
    const worldVector = stdVector.unproject(this.defaultCamera);
    
	//获取摄像机世界坐标
    let cameraPos = this.defaultCamera.getWorldPosition(new Vector3());
    //获取射线方向
    let dir = worldVector.clone().sub(cameraPos).normalize();;
    //沿着射线方向延伸100个单位
    let src = cameraPos.clone().add(dir.clone().multiplyScalar(100))
    
    this.createSphere(src);
}

//在指定的位置生成一个球
createSphere(pos){
    var geo = new SphereBufferGeometry(0.5);
    var mat = new MeshStandardMaterial();
    var s = new Mesh(geo,mat);
    this.scene.add(s);
    s.position.copy(pos);
}

请添加图片描述
中间点在模型上没有出现是因为生成在模型后面了。

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值