泄露
泄露属于是hammer编辑器的一种漏洞(bug),是当地图没有封闭好,或者有实体在地图外(即虚空)之中而引起的一种BUG,此时编译器应会报错,而地图也通常无法正常运行。BSP 地图本身必须保证完全封闭。关卡内部,即世界的任何部分不能和外部,即虚空 相连。即便是天空也必须要用tools/toolsskybox
纹理的固体封闭地图。当地图没有封闭好,或者有实体在虚空,则在编译地图的时候VBSP 就会发生泄露事故,当这种情况发生时,VBSP 无法判定地图的哪部分在内部,哪部分在外部,使得无法正常编译地图。
此案例展示了一个在几何方面上具有明显空隙的固体。这会导致编译过程中出现泄露信息:
当这样的地图被编译时,与虚空之间存在间隙,VBSP 会在编译日志中生成与此类似的错误:
ProcessBlock_Thread: 0...1...2...3...4...5...6...7...8...9...10 (0) **** leaked **** Entity light (-1607.69 -1094.12 -183.00) leaked!
出现此错误消息后,VBSP 会告诉您关卡中存在泄漏,以及它试图从虚空进入关卡时找到的第一个实体(本案例以范围光为示例)。它还以X、Y和Z坐标为您提供该实体的位置。
泄露所带来的影响
关卡中的泄露会导致许多不良影响. VBSP 会报告泄露,并且不会正确生成Portalfile(实际上根本不会生成) (mapname.prt
),.VVIS 使用Portalfile进行渲染计算.因为没有Portalfile,VVIS将无法正常运行. 当发生泄露时, VRAD 也会无法正常工作,或只进行照明,而不进行光线反射.
地图通常根本无法运行.VVIS可能会直接渲染整张地图,这对帧数不利,或直接整个区域都不可见.更坏的情况是,VRAD会直接把地图渲染成黑色.
别浪费时间在泄露上
VBSP (编译窗口)会提示任何泄漏。在地图完全制作好而花上几个小时去完全编译时才发现有泄露,这根本没有效率。在开始检视地图的vis与光照之前,请确保地图没有泄漏。如果发现在编译过程中VBSP (编译窗口)提示泄漏,请按Ctrl+C中止编译。
寻找泄露
有时泄露并不像上面的示例那么明显.可能只是因为一些失误而造成的. VBSP 为你提供了一个pointfile 去帮助你找到泄露的实体.它被渲染成从虚空到编译报告中所描述的实体的一条红线.在发生泄漏事故后, a mapname.lin
将会生成于vmf的同一目录下.
加载Pointfile
加载pointfile可以使Hammer编辑器的视图里精准显示地图内有哪处地方泄露 ; 使用方法: 在hammer编辑器上方栏里找到map,然后再点选Load Pointfile即可
右图为加载pointfile的示例。标示红线于 3D 和 2D 视图中,并且该红线是以实体为中心而向外散发至地图外部(即虚空)
通过加载pointfile,你可以沿着红线找到泄漏源。最好从VBSP 指定的实体(也就每次地图编译时弹出的编译窗口里显示的一串红字标示的实体)开始找起,然后沿着红线走,直到找到地图中缺口。把洞补上并重新编译地图以查看你是否已修复泄漏。
通过坐标点找到泄露处
如果您在定位泄露实体时遇到问题时,可以使用视图菜单上的转到Go to Coordinates来查找实体和红线的起点。只需输入VBSP 报出的实体泄露坐标,2D 和 3D 视图就会跳转到出现泄露问题的实体。按照泄露实体延伸出的红线找到地图泄漏的洞口。
另一种查找泄漏源的方法是在加载pointfile后,缩小2D视图直到看到红线。沿着这条线找到并选取实体。然后从 View 菜单中选择 Center 3D Views on Selection。接着就能按照泄露的实体延伸出的红线找到地图泄漏的洞口。
其他可能引发泄露的情况
这里是说明除了地图盒子上有缺口引发的泄露外,还有其他可能导致 VBSP 产生泄漏错误的错误。
实体泄露
所有实体都需要位于用固体拉盒子的或skybox内,总之就是封闭环境内。 要注意VBSP将所有brush实体视为不存在,因此不可将画笔实体(比如func_door 实体)用于密封地图或补上缺洞。
构建不当的Areaportals笔刷
当没有正确密封好areaportal 时,编译器也会生成泄漏错误提示,使用与上边提到的查找泄漏的方法也同样可以查找areaportals泄漏。
特殊几何不封闭体泄露
Displacements 和water 没封好也会导致泄漏。你可以通过在它们后面拉固体封上来解决这种类型的泄漏。使用带有tools/toolsnodraw
材质的笔刷密封,不会增加任何额外的渲染负担,因此比较推荐这样做。而水则应该在其上面区域进行密封(用于密封的笔刷纹理可以是tools/toolsskybox
或其他类型的纹理,比如brick纹理。)不要使用nodraw纹理的笔刷来密封水,因为这会导致奇怪的拖尾效应。
不匹配的实体原点
泄漏原因可能是任何具有origin helper的实体,例如func_door_rotating 或func_rot_button 。虽然实体本身可能在世界内部,但如果origin helper在地图之外,其实体也会导致泄漏。如果你在2D视图里找到个点向地图外的虚空射出红线,并且红线的方向那里没有实体,那么就是泄露了
快速判断实体是否导致泄漏的方法是:
- 加载pointfile.
- 通过坐标点找到泄露处.
- 从上方栏找到Edit点选Select All.
- 确定在上方栏的View里勾选上Show Helpers.
- 如果你看到在pointfile(红线)处出现了一个origin helper,那这便是问题所在.
如果您有一个导致泄漏的origin helper,您可以选择手动将其移回地图内,使用Tools中的Center Origins,或者只需右击origin helper并选取Center on entity。
当具有这些helper之一的笔刷实体在 Solids 模式下移动时,通常会出现不匹配的实体origins。在solids mode之下移动笔刷实体不会移动其origin helper。.
透明笔刷
如果在地图边缘使用半透明纹理(如玻璃)的笔刷时也会导致泄漏。如果pointfile(红线)通过笔刷时,请检查该笔刷所有面的纹理。
Func_viscluster
当Func_viscluster 穿过Areaportal表面或太靠近它们时,也会导致泄漏。此时应该禁用所有func_visclusters并重新编译以查看泄漏是否消失。
虚假泄漏
尽管非常罕见,但是VBSP还是有可能在你编译地图时报告假泄漏,如果你确定VBSP报告的泄漏是不应该出现的,那么你可以把你的地图复制粘贴到新的地图文件中。如果编译成功,那么你之前的文件可能损坏了。
结论: 预防胜于修补
通过加载pointfile可以相对轻松地查找泄漏,但修复泄漏的最重要方法之一是防止泄漏。在构建地图时花点时间,并确保每个笔刷正确地对齐网格,这对于在泄漏问题上大有帮助。你的地图结构越规范、越有条理,你就越有可能在泄漏发生时易于发现问题,甚至可以采取行动避免泄露的发生。你还可以在每做一点场景时就快速编译检查一下有没有什么问题,而不是在地图制作完成时才来编译。在地图仅完成部分时查找泄漏比在充满各种固拼的完整地图中查找泄漏要容易和快捷得多。