📜  从相机到鼠标统一的光线投射 - C# (1)

📅  最后修改于: 2023-12-03 15:36:19.551000             🧑  作者: Mango

从相机到鼠标统一的光线投射 - C#

在3D计算机图形学中,光线投射是一种基本的技术。它允许获取从摄像机到一个点的光线,并将其用于各种任务,例如鼠标点击检测、阴影计算、反射和折射等等。在这篇文章中,我们将讨论如何从相机到鼠标位置进行光线投射。

算法

我们的目标是使用鼠标位置和相机数据创建一条光线。算法的第一步是将屏幕坐标转换为3D空间坐标。这需要投射光线从相机到该点,并在三维空间中找到这条光线与物体的交点。以下是我们需要进行的具体步骤:

  1. 将鼠标位置转换为屏幕坐标。
  2. 将屏幕坐标转换为NDC范围(-1.0,1.0)内的坐标。
  3. 将NDC坐标转换为相机空间坐标。
  4. 找到从相机位置到鼠标位置的向量。
  5. 标准化向量以获得单位方向向量。
  6. 创建包含射线方向和起点位置的光线。
代码实现

让我们从实现第一步开始,即将屏幕坐标转换为NDC坐标。我们可以使用以下代码:

Vector3 ndc = new Vector3(
    (2.0f * mousePosition.x) / Screen.width - 1.0f,
    (2.0f * mousePosition.y) / Screen.height - 1.0f,
    0.0f);

我们将鼠标位置除以屏幕大小,然后将其乘以2.0,并减去1.0,以获取NDC坐标。这会将所有值转换为范围(-1.0,1.0)内的值。

接下来,我们需要将NDC坐标转换为相机空间坐标。我们可以使用以下代码获得相机空间坐标:

Matrix4x4 inverseProjection = camera.projectionMatrix.inverse;
Vector4 cameraSpacePos = inverseProjection * new Vector4(ndc.x, ndc.y, -1.0f, 1.0f);
Vector3 cameraSpace = new Vector3(cameraSpacePos.x / cameraSpacePos.w, 
                                   cameraSpacePos.y / cameraSpacePos.w, 
                                   cameraSpacePos.z / cameraSpacePos.w);

我们使用相机的逆投影矩阵将NDC坐标转换为相机空间坐标。然后,我们使用除以w分量的方式将其缩放到正确的比例。

现在,我们需要找到从相机位置到鼠标位置的向量。我们可以使用以下代码来计算:

Vector3 rayDirection = cameraSpace - camera.transform.position;

我们从相机空间坐标中减去相机位置来获取起点位置,并将其乘以-1以获取向量方向。

我们还需要标准化向量,这可以通过以下代码实现:

rayDirection.Normalize();

现在,我们创建光线。我们可以使用以下代码来创建光线:

Ray newRay = new Ray(camera.transform.position, rayDirection);

我们将相机位置作为起点位置,并将标准化的向量作为方向。

现在我们已经完成了从相机到鼠标位置的光线投射算法的实现!

结论

在3D计算机图形学中,光线投射是一种基本技术。在本文中,我们讨论了如何从相机到鼠标位置进行光线投射。通过将屏幕坐标转换为NDC范围内的坐标,然后将其转换为相机空间坐标,并找到从相机位置到鼠标位置的向量,我们可以创建一个包含射线方向和起点位置的光线。