通过Unity3D中的门户时如何融合两个摄像机


18

在提出问题之前,我知道最明显的解决方案是使用规范化的视口矩形,但是我需要比矩形更复杂的形状,并且我考虑使用视口矩形,但似乎没有是我的解决方案。

编辑:有些人对我的问题感到困惑,让我再详细一点。 在此处输入图片说明 发生的情况是,随着玩家进入一个门户,我创建了一个克隆的FPS控制器,然后将其移出了另一个。这给了我两个摄像头,以及您在右上方看到的视图。它只是显示一台摄像机,并剪辑门户。我想要的是与此类似的东西摄像机融合在一起,创造出平滑过渡的错觉。我想做的是删除所有绿色底纹图像中的所有内容,并将其替换为其他相机。这样一来,您可以获得摄像机A的视图从门户中移出的峰值,并与摄像机B的视图在另一个门户中移出的峰值相融合,以获得一个完整的图像。随着您在门户中的移动,切割也会相应地更改。

我一直在设计门户网站系统,但我的所有工作都陷入了困境,包括让玩家流畅地通过门户网站。我现在的主要问题是获得Valve的相机混合效果。我需要两个摄像头将它们无缝融合在一起,就好像您正在通过门户戳头一样。它不能只是一个矩形,它必须匹配,但是玩家正在通过门户进行查找。

我目前最好的方法是在每个门户后面投影一个深度蒙版着色器,然后将您正在旅行的门户中的相机制作成仅深度的。然后以某种方式混合两个摄像机。我的主要问题是弄清楚我该怎么做,如何使第二台摄像机仅渲染门户网站之外的内容,而其余默认设置为摄像机1来获得一个全屏投影。

如果您可以给我一些想法,或者解释一下如何使用深度蒙版着色器来实现这一点,那将是极大的帮助。我将继续努力,并在取得突破时进行更新。


5
您能详细说明“相机混合效果阀的作用”吗?我了解,在门户网站渲染中,单个摄像机就足够了。在第一人称游戏中,它会附加到玩家上,并在与玩家一起穿过门户时自动转换到新位置。为了渲染门户效果,将渲染场景的变形副本。这也可以用第二台摄像机来实现,但是这些摄像机之间不应该有任何融合。
msell,

1
我已经完美地降低了视觉效果。我正在尝试做的是弄清楚如何获得通过门户的效果。我已经拥有了所有的角色图形,并且移动非常顺畅,我只需要从第一人称视角看就可以使它看起来平滑。
Timothy Williams

1
我敢肯定,如果他们明白这是什么,那么许多人都将为您提供帮助。您确实需要更好地说明问题,也许添加图片,甚至是可视化错误视频的视频。
msell 2013年

2
您能否在效果示例视频中添加链接?
Mike Baxter

2
如果仅使用一个摄像机/ FPS控制器怎么办?当摄像机在门户中移动时,可以将其转换为新的位置和方向。如果门户网站渲染正确,则过渡应该是无缝的,并且不需要混合。
msell 2013年

Answers:


6

了解问题

从我可以看到的问题来看,您所描述的问题是相机的近平面与门户定义的平面相交的结果。发生此交叉时,您可以在门户背后的墙后面看到。

这类似于其他游戏中玩家从水上过渡到水下时遇到问题。如果相机正好在水面之上,则不会应用后期处理效果来模糊玩家的视线(使其变暗,变模糊和变蓝)。因此,如果近平面的底部在水下,则玩家可以清楚地看到在水下。

如果我是正确的,则可以在定义投影矩阵时通过更改此平面的位置来确认。随着从摄像机原点到近平面的距离增加,问题也应增加。

简单的解决方案

使近平面非常接近相机应该可以消除此问题。该解决方案不是一个完整的解决方案,但在绝大多数情况下将产生足够好的结果,并且是有效的。

完整的解决方案

如果仅使近平面靠近相机不满足要求,则可以创建一个“遮罩”以混合通过从播放器和门户的角度渲染场景而生成的图像。

假设只允许将门户应用到平坦的表面,则可以计算相机的近平面与门户定义的平面(或门户所在的墙)之间的相交线。此行会将屏幕分为两部分。确定屏幕像素在线条的哪一边将让您知道要使用哪个渲染图像,门户图像或播放器摄像机图像。

请记住,如果发生此问题,则摄像机视锥台必须完全位于门户内,因此相交线将始终从一个屏幕边缘完全切割到另一屏幕边缘。

此链接应有助于数学查找线。下面的代码应该大致正确。

相交线是使用线上的点和线的方向定义的。下方交点方向是使用门法线和摄像机视线方向(近平面法线)的叉积计算的。通过从近平面上的点直接朝向门平面(沿着门法线)投射射线并找到相交点,可以给出线上的点。

Vector3 intersectionDir = Vector3.cross(portalNorm, viewDir);
Ray ray = new Ray(camPos + viewDir * camNearPlaneDist, portalNorm);
Vector3 intersectionPos = ray.intersects(new Plane(portalVert1, portalVert2, portalVert3);

确保viewDir是单位向量。portalVert1、2和3只是用于Portal贴花或其上的表面的4个顶点中的3个。还有其他方法可以定义门户所在的平面,但是我认为这是最容易获得的信息。

一旦有了这两个向量来定义相交线,就将它们分别乘以视图,然后再将其投影矩阵以将其置于屏幕空间中。

然后,您可以使用后期处理着色器来混合这些图像。通过确定当前像素位于分界线的哪一侧,可以选择在每个像素处使用哪个图像。这是通过获取像素位置(这也是用于查找渲染目标texel的位置)并执行的;

float d = (pixelX - intersectionPos.X) * intersectionDir.Y - (pixelY - intersectionPos.Y) * intersectionDir.X;

通过d大于还是小于0给出边。如果正好是0,那么您就在网上。

有关以上数学的参考,请参见this

创建深度蒙版/模板缓冲区以从门户网站透视图渲染之前使用时,也可以使用此方法。您可以创建一个全屏四边形,然后使用该行对其进行切片。


接近剪裁平面是个好主意,但不完全是我想要的。第二部分是一种有趣的方法。目前,我在出口门平面后面的所有区域都使用深度蒙版着色器,然后将出口相机的clear标志设置为仅depth。这样一来,现有摄影机中从门户到达峰值的任何部分都会在屏幕上绘制,而进入摄影机则会在深度蒙版上绘制,因此它通过混合每个摄影机中达到峰值的部分来创建一个图像。各自的门户。唯一的问题是我遇到了一些较小的剪辑问题,例如
Timothy Williams

玩家穿越时略有混蛋。您提出的这个想法听起来很有希望。因此,本质上,我需要做的是沿着摄像机靠近平面和门户平面相交的屏幕计算线,方向给我线的方向,点是线的各个点。然后如何在着色器/脚本中确定像素位于分隔线的哪一侧?
蒂莫西·威廉姆斯

我对答案做了一些更新,以提供一些基本代码。确保尝试在剪切平面距离附近更改视图以确认问题。使它尽可能小也可能就足够了。请记住,使其正常运行,然后快速正常运行。
OriginalDaemon


我确实测试了更改近剪裁平面距离的方法,这使问题稍微好了一些,但是正如Mell所发表的文章指出,这种方法在穿越时无法解决问题。我仍然觉得相交线可能会起作用,所以我将尝试一下。我还将进一步研究Mell发表的那篇文章。最终将取决于深度遮罩是更快还是该相交线更快
Timothy Williams

3

建议的答案非常好,但最终我还是选择了另一种使用深度遮罩的技术。

您要做的就是获取脚本和着色器,将脚本放置在场景中具有渲染器的每个对象上,并将渲染队列设置为3020(我将发布一个脚本,以便稍后使用)。

然后,在两个门户网站的后面创建一个飞机箱(所有飞机都朝内,在图中看不到最靠近您的那一侧,但是当您在飞机箱内时,应该看到的是灰色的)像这样: 在此处输入图片说明 将它们设置在它们自己的特殊层上(我为我选择了“ DepthMask”),然后在上面添加了带有着色器的材质。 在此处输入图片说明

然后,您拿起主摄像头,并从其剔除蒙版中取消选中特殊图层(我未选中DepthMask图层),并将其深度设置为0。 在此处输入图片说明

然后,当您穿越并克隆摄像机时,将另一台摄像机的清除标志设置为“仅深度”,并将其深度设置为1。 在此处输入图片说明

然后,您将获得一个无缝屏幕,在两个摄像机视图之间混合。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.