嘿,

我正在为游戏 REPO(UNITY中实现)开发一个门槛枪模块,并正在实施经典门槛渲染系统使用配对摄像机。

每个门槛都有自己的摄像机。想法是:

  • 总共有3个摄像机:玩家摄像机、蓝色门槛摄像机和红色门槛摄像机
  • 各个门槛在其表面渲染另外一个门槛的摄像机
  • 门槛摄像机的位置相对于玩家摄像机来定位,以模拟通过门槛的效果

问题是:

一切似乎都在同一墙壁上,两个门槛都正对面的方向工作正常。

但是,一旦门槛放置在不同方向的墙壁上,骗人的效果就会被打破。

我对自己认为的问题的信心很高,但我却无法恰当地识别问题。

下面是它本该如何运作:

假设:

  • 玩家站在蓝色门槛前方5个单位,正面看它
  • 蓝色门槛应该绘制出玩家站在红色门槛后方5个单位时看到的东西

我相信门槛的新位置或新定位是错误的,但我不确定如何修复它。

这是给定门槛的更新代码(注意:SetNearClipPlane函数不是我自己的,它来自Sebastion Lague的[ Coding Adventure:门槛](https://www.youtube.com/watch?v=cWpFZbjtSQg&t=811s)所以要归功于Sebastion Lague):

还有最后一件事情,抱歉,我的编码水平并不高,所以我的代码格式可能不清晰。我会解释一下它是如何设定的。

Portal类:

  • PortalCamera类
  • PortalScreen类

PortalCamera仅仅是对Camera类的包装.getCamera()仅仅返回内部的Camera对象。PortalScreen是对四角形的包装。有其他东西像的是一个渲染纹理和一个网格渲染器,但这些并不重要。getScreen()返回内部的四边形。

void SetNearClipPlane(Camera playerCamera)
{
    Transform clipPlane = portalScreen.GetScreen().transform;
    int dot = System.Math.Sign(Vector3.Dot(clipPlane.forward, transform.position - portalCamera.getCamera().transform.position));

    Vector3 camSpacePos = portalCamera.getCamera().worldToCameraMatrix.MultiplyPoint(clipPlane.position);
    Vector3 camSpaceNormal = portalCamera.getCamera().worldToCameraMatrix.MultiplyVector(clipPlane.forward) * dot;
    float camSpaceDist = -Vector3.Dot(camSpacePos, camSpaceNormal);
    Vector4 clipPlaneCameraSpace = new Vector4(camSpaceNormal.x, camSpaceNormal.y, camSpaceNormal.z, camSpaceDist);
    portalCamera.getCamera().projectionMatrix = playerCamera.CalculateObliqueMatrix(clipPlaneCameraSpace);

}

public void UpdatePortalCamera(Camera playerCamera)
{
    if (!finishedInitialization)
        return;

    if (LinkedPortal == null)
    {
        Debug.Log("Linked Portal是null在Portal摄像机更新...");
        return;
    }

    Transform source = portalScreen.GetScreen().transform;
    Transform target = LinkedPortal.getPortalScreen().GetScreen().transform;

    Vector3 localPos = source.InverseTransformPoint(playerCamera.transform.position);
    Quaternion localRot = Quaternion.Inverse(source.rotation) * playerCamera.transform.rotation;

    Quaternion portalRotation = Quaternion.Euler(0f, 180f, 0f);

    localPos = portalRotation * localPos;
    localRot = portalRotation * localRot;

    portalCamera.getCamera().transform.position = target.TransformPoint(localPos);
    portalCamera.getCamera().transform.rotation = target.rotation * localRot;

    SetNearClipPlane(playerCamera);

}

未更新摄像机视频:

https://reddit.com/link/1rzg8bq/video/8gc302pf5bqg1/player

更新摄像机视频:

https://reddit.com/link/1rzg8bq/video/u0cr565k5bqg1/player