Unity ScreenToWorldPoint精度不够

开发中遇到float精度不够

 Vector3 worldPos = mMapCamera.ScreenToWorldPoint(screenPos);
 Vector3 tempPos = mMapCamera.WorldToScreenPoint(worldPos);

上面代码执行后screenPos不等于tempPos ,找了半天发现是float精度不够,最后自己重写ScreenToWorldPoint来解决

public Vector3 ScreenToWorldPoint(Vector3 screenPos) {
            double screenX = screenPos.x;
            double screenY = screenPos.y;
            double screenZ = screenPos.z;

            //反齐次除法,求出裁剪空间坐标
            Matrix4x4 pMatrix = mMapCamera.projectionMatrix;
            double px = screenX / Screen.width;
            px = (px - 0.5f) * 2f;
            double py = screenY / Screen.height;
            py = (py - 0.5f) * 2f;
            double pz = (-screenZ - pMatrix.m23) / pMatrix.m22;
            double pw = screenZ;
            px *= pw;
            py *= pw;
            //裁剪空间到相机空间
            Matrix4x4 pInverseMatrix = mMapCamera.projectionMatrix.inverse;
            double vx = (pInverseMatrix.m00 * px + pInverseMatrix.m01 * py + pInverseMatrix.m02 * pz + pInverseMatrix.m03 * pw);
            double vy = (pInverseMatrix.m10 * px + pInverseMatrix.m11 * py + pInverseMatrix.m12 * pz + pInverseMatrix.m13 * pw);
            double vz = (pInverseMatrix.m20 * px + pInverseMatrix.m21 * py + pInverseMatrix.m22 * pz + pInverseMatrix.m23 * pw);
            //观察空间到世界空间
            Matrix4x4 vInverseMatrix = mMapCamera.worldToCameraMatrix.inverse;
            double x = (vInverseMatrix.m00 * vx + vInverseMatrix.m01 * vy + vInverseMatrix.m02 * vz + vInverseMatrix.m03 * 1);
            double y = (vInverseMatrix.m10 * vx + vInverseMatrix.m11 * vy + vInverseMatrix.m12 * vz + vInverseMatrix.m13 * 1);
            double z = (vInverseMatrix.m20 * vx + vInverseMatrix.m21 * vy + vInverseMatrix.m22 * vz + vInverseMatrix.m23 * 1);
            return new Vector3((float)(x), (float)(y), (float)(z));
        }
        public Vector3 WorldToScreenPoint(Vector3 worldPos) {
            double worldX = worldPos.x;
            double worldY = worldPos.y;
            double worldZ = worldPos.z;

            //世界空间到观察空间
            Matrix4x4 vMatrix = mMapCamera.worldToCameraMatrix;
            double vx = (vMatrix.m00 * worldX + vMatrix.m01 * worldY + vMatrix.m02 * worldZ + vMatrix.m03 * 1);
            double vy = (vMatrix.m10 * worldX + vMatrix.m11 * worldY + vMatrix.m12 * worldZ + vMatrix.m13 * 1);
            double vz = (vMatrix.m20 * worldX + vMatrix.m21 * worldY + vMatrix.m22 * worldZ + vMatrix.m23 * 1);
            //相机空间到裁剪空间
            Matrix4x4 pMatrix = mMapCamera.projectionMatrix;
            double px = (pMatrix.m00 * vx + pMatrix.m01 * vy + pMatrix.m02 * vz + pMatrix.m03 * 1);
            double py = (pMatrix.m10 * vx + pMatrix.m11 * vy + pMatrix.m12 * vz + pMatrix.m13 * 1);
            double pz = (pMatrix.m20 * vx + pMatrix.m21 * vy + pMatrix.m22 * vz + pMatrix.m23 * 1);
            double pw = (pMatrix.m30 * vx + pMatrix.m31 * vy + pMatrix.m32 * vz + pMatrix.m33 * 1);
            //齐次除法
            double x = px / pw;
            double y = py / pw;

            //转到0-1的范围
            x = (x * 0.5) + 0.5;
            y = (y * 0.5) + 0.5;
            return new Vector3((float)(x * Screen.width), (float)(y * Screen.height), (float)(-vz));
        }
  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

achonor

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值