Areaportal
Areaportal 是一个笔刷(固体)实体 ,func_areaportal
,func_areaportalwindow
,可以用来"密封"两个单独的可见性分支区域 和控制可见性。
Areaportal 有两个不同的目的:剔除几何体并从渲染中移除整个区域。
Areaportal 就像是打开或关闭的门。当 Areaportal 关闭时,它阻挡在后部分区域的几何图形和其它物体的可见性。当它打开时,几何体将再次可见。 Areaportal 可以在引擎运行时动态打开和关闭。它们通常被设置为使用实体 I/O 系统 或通过与门 实体的链接从一系列trigger_multiple
笔刷打开和关闭。
Contents
属性
对于 Areaportal 而言:
- 绑定到了
func_areaportal
实体上。 - 必须仅由一个固体构成。绑定了多个固体的 Areaportal 实体在 vbsp ① 编译时会产生错误。
- 必须使用应用于 Areaportal 固体的所有面的
tools\toolsareaportal
纹理。 - 不能包含置换表层 ②,如果包含会产生 vbsp 错误。
- 必须用于密封它们连接的所有区域,以避免泄露 ③。
- 是有体积的,而不是单个表面。尽管 Areaportal 可以是任意大小,但通常它们由与它们连接的区域(门口)大小相同的细节笔刷构成。
- 在 Areaportal 体积的大小生成一个新的可见性分支区域 。
- 可以根据输入与输出 或通过将它们附加到门实体来设置打开或关闭。
areaportal_window
func_areaportalwindow
实体表现得像一个标准的 Areaportal,如果玩家移动到了指定的距离,则开始淡出和关闭。这避免了 Areaportal 突然弹出式地打开。
——————
① vbsp:VBSP 是将原始 VMF 文件编译为二元空间划分格式(BSP)。
② 表层位移:指玩家所说的地形。
③ 泄露:导致地图与地图之外的虚空相连的一个口。会导致地图无法编译。
Areaportal 在地图编辑中的实现
- 使用单个固体 实体创建 Areaportal 的体积,(并用它)完全密封你想控制的两个区域之间的空间。(如有必要,多个 Areaportal 可以一起执行此操作①。不要给任何一个 Areaportal 实体提供六条以上的边。②)
- 如果 Areaportal 像门口一样连接两个区域,则让 Areaportal 的固体大小为这个门口的大小,并且其厚度与其连接的墙壁(的厚度)相同。如果区域是开放区域,例如室外部分,则厚度可以是任意大小(典型的网格大小为 8、16、32 等)。
- 将
tools\toolsareaportal
材质应用到笔刷的所有面。 - 将画笔绑定 到 func_areaportal 或 func_areaportalwindow 实体。
- 设置 Initial State(初始状态)键值,以便它不会在不应该阻止可见性时关闭。如果你想把它链接到一个命名的门,将 Areaportal 的 Initial State 键值设置为与门相同的初始状态,并将门的名称填入 Areaportal 的键值 Name of Linked Door(链接的门的名称)中。当门关闭时,Areaportal 的 Initial State 也应为关闭,反之亦然。
——————
① 多个 Areaportal 可以一起执行此操作:就是可以用几个 Areaportal 密封泄露口。
②“不要给任何一个 Areaportal”一句:原文为:Avoid giving more than six sides to any single areaportal entity.
性能影响
打开的 Areaportal (无论它们总是打开还是触发打开)通过看这个 Areaportal 可以知道(它)具有剔除①几何体的行为。这跟透过房子的敞开窗户看一样,只有通过 Areaportal 直接可以被看到的可见性叶子块 会被引擎渲染。通过这种方法,下一个区域中的几何体被粗略地“剔除”到 Areaportal 的大小,减少了渲染的几何体数量,并提高了性能。最重要的是,模型(道具)几何体根本不会被渲染,除非模型的一部分通过区域门户的视锥体(view frustum)(或可见角度)直接可见②。这让处于打开状态的 Areaportal 对于控制模型几何图形的可见性非常有用。
由于这些性能优势, Areaportal 通常在始终打开(always-open)状态下使用。通过将func_areaportal
实体上的“Initial State(初始状态)”键值设置为“打开”来创建始终打开的 Areaportal。始终打开的 Areaportal 用于通往包含大量视觉和几何形状的其他区域的开口。例如,简单地在走廊的尽头放置一个始终打开的 Areaportal,通向更广阔的空间,可以产生显著的性能提升。当玩家在里面时,从门口向外看,(引擎)只会绘制通过门口直接可见的每片叶子③中的几何图形。
过度使用
必须小心避免同时可见太多的 Areaportal。每个都有处理成本,如果 Areaportal 没有剔除足够的细节,没有它们的场景绘制速度会更快!
Areaportal 不会在已编译的地图中形成笔刷,因此不会计入笔刷块的大小限制。当你拥有非常完整的 BSP 并使用大量提示时,会很有用。
——————
① 剔除:这里指看不到的部分不会被渲染,即从渲染中剔除掉看不到的部分。
② 可见:可以被看见。
③ 叶子:在起源引擎中一般指“可见分支区域”,英文为“(vis)leaf”“(vis)leaves(pl.)”。详情请参阅该条目 。
编译
重要的是,Areaportal 应该封锁的任何区域都不要彼此泄漏 。与常规泄漏一样,只有当地图的一个区域完全被世界(非实体)固体(Areaportal 笔刷除外)包围且没有空隙时,才认为该地图区域与另一个区域是密封的。如果区域有多种连接的路线,则每条路线的出入口都必须放置一个 Areaportal。
想象一个装满水的鱼缸两侧有几个孔可能会有所帮助你理解。一个 Areaportal 必须填补这些漏洞中的每一个,否则该区域将泄漏,由 vbsp 产生 leak 错误。
必须使用 Areaportal 来密封该区域的每个入口。func_detail 笔刷 、半透明纹理和表层位移 无法封闭区域,并且会产生泄漏,从而阻止地图运行。如果编译器仍然可以在任何一个 Areaportal 的两个主要表面之间找到一条路,它将报告 Areaportal 泄漏。
识别编译错误
Areaportal 编译错误由 VBSP 输出。如果发生泄漏,你将看到:
Brush <brush number>: areaportal brush doesn't touch two areas done
这些错误消息有时不像正常的泄漏 错误消息那样容易发现,但是当涉及到在地图中定位泄漏时,vbsp 会生成一个点文件来帮助你,就像常规几何泄漏一样。
Areaportal 和水
使用 Areaportal 的另一个棘手方面是它们不允许跨越水边界,如水面。要在水中搭建 Areaportal,你需要将 Portal 分成两部分——一个 Areaportal 在水面上方,另一个 Areaportal 位于水面下方——以便它们都在水面相遇。
合并
出于优化原因,引擎会自动合并共享同一平面(对齐)的 Areaportal。如果不需要这种行为,只需确保 Areaportal 笔刷不在同一平面上。这通常很简单,只需在编辑器中稍微缩小或移动一个 Areaportal,使其不再对齐。即使是一个网格单位也足以避免自动合并。
r_DrawPortals 1
控制台命令查看引擎中是否正在合并 Areaportal。穿过区域查看
Areaportal 只在它们封闭的区域之间进行剔除。根据右图思考:虽然建筑物的内容如你所料被剔除,但第一和第二个可视性分支区域 ①之间的可见性不受影响,因为它们通过建筑物的侧面相互连接。
这可以通过在建筑物的两侧创建另外两个 Areaportal 来解决。
——————
① 可视叶:可见性叶子块。
② 叶:叶子块,同上。
控制台命令
你可以使用一些特定于 Areaportal 的控制台 变量在游戏中调试和测试 Areaportal:
- r_DrawPortals 0/1
- 当设置为“1”时,以绿色渲染出任何 Areaportal 的表面边界(两个区域之间)。有时不止一个 Areaportal 被压缩成一个。如果属于它的 Areaportal 是打开的,还会绘制第二个绿色边框,显示另一侧的可见性被切割后的内容。
- mat_wireframe 0/1/2/3
- 以线框模式绘制几何图形,可以轻松查看地图中 Areaportal 的效果。在调试 Areaportal 时,你通常应该将 mat_wireframe 设置为“1”或“2”,因为“3”设置可以隐藏实际渲染的几何体。
- r_portalscloseall 0/1
- 将此设置为“1”会强制关闭所有 Areaportal (因此它们无法打开)。覆盖
r_portalsopenall 1
。(如果没有效果,请重试此操作。它可以告诉你问题是否只是 Areaportal 没有正确关闭。)
- r_portalsopenall 0/1
- 将此设置为“1”会强制所有区域门户打开(因此它们无法关闭)。
BindToggle
控制台命令允许使用单个键来切换控制台变量。在多人游戏中
Areaportal 在多人游戏中非常有用。它们的创建与单人游戏中的相同,但它们的功能和用法略有不同。由于游戏服务器中有多个玩家,因此对 Areaportal 何时打开的控制较少,并且需要针对最坏情况场景(即所有可见 Areaportal 都打开时)优化关卡性能。因此,在大多数情况下,最常放置“始终打开”的 Areaportal①,其次是与门链接的 Areaportal,然后是由触发器②控制的 Areaportal。在最坏的情况下,精心设计的“始终开放”Areaportal 将比旨在触发的门户提高性能。
Areaportal 窗户 也可用于多人游戏中的密封结构,但不太有用,因为它们会在竞争性多人游戏中造成游戏玩法不平衡。靠近 Areaportal 窗户的建筑物内的玩家可以看到外面的任何玩家,但外面较远的玩家将无法看到里面的玩家。
——————
① “始终打开”的 Areaportal:通过设置键值“Initial State”为“Open”并且没有任何实体I/O关联的 Areaportal 来实现。
② 触发器:一般指以“trigger_”开头的实体,通常是固实体。这类实体统一使用tools/toolstrigger
纹理。
与遮挡器(occluder)的关系
Areaportal 类似于 Occluder ,因为它们有助于控制可见性。它们之间的主要区别是:
- Occluder 仅隐藏其背后的模型(道具)几何体。Areaportal 隐藏所有类型的对象。
- Areaportal 必须完全密封区域(不允许出现泄漏 ),而 Occluder 可以是独立的内部区域。
- Occluder 的每个对象比开放的 Areaportal 更昂贵。
- Occluder 可以根据屏幕区域控制它们将隐藏的对象的大小。
另请参阅
- func_areaportal /
CAreaPortal
- func_areaportalwindow
CAreaPortalOneWay
(新实体的 C++ 代码)- Controlling Geometry Visibility and Compile Times
- Leak
- Visleaf