可见性优化

若不使用VIS ,地图中的所有内容都会持续渲染(无论玩家是否可见),这将严重影响游戏性能(和帧率)。显然需要精简渲染对象列表,但如何实现?若逐一测试每个对象或表面的可见性,耗时将远超直接渲染!
游戏引擎采取折中方案: 金源和
起源均采用基于
约翰·卡马克在
雷神之锤中实现的二进制空间分区(BSP) 模型。本页详解其工作原理及优化方法。
空间分区
BSP地图的内部空间(即未被世界笔刷 占据的区域)被划分为可视分区 。这些3D空间之间的可见性关系在地图编译时计算,并嵌入地图文件供引擎调用。与笔刷相同,分区始终为凸面体。
左图展示了U型走廊可能产生的分区(为清晰展示添加了间隙)。分区1与3之间无视线连接,因此当摄像机位于其中一个分区时,另一个分区的内容不会渲染。引擎只需查询地图内嵌的可见性图表即可完成此判断。
但分区2存在问题:当摄像机位于该分区时,[[Zh/
- File:Frustum culling.png|视锥剔除]] 之外,所有三个分区的内容都会被渲染——即使左侧墙面已完全遮挡视野。后文将介绍解决工具,但请注意:多数情况下,修复问题的性能消耗可能高于直接渲染非最优场景。
重要提示:




优化VIS编译时间
VVIS ( 金源中为VIS /HLVIS )负责计算分区间的可见性(而VBSP (或QBSP2 /HLBSP )创建分区)。即使最复杂的地图也应只需数分钟完成编译,若超时请尝试以下方案:
- 合理使用Detail笔刷
- 尽量使世界笔刷 对齐网格,优先采用2的幂次尺寸
- 避免过度使用雕刻/顶点编辑等工具修改基础笔刷
- 在视野开阔区域放置func_viscluster(存在于自
以来),其内部分区将被视为相互可见
- 避免创建无交互的大型开放区域,用3D天空盒 缩减天空尺寸,并为位移贴图 添加基底笔刷
请注意:VIS编译时间与游戏性能是两回事。若缩短编译时间会损害优化效果,延长编译可能是值得的。
检查分区
自 起源2007起,Hammer新增"地图 > 加载门户文件"功能,可在3D视图中用蓝色粗线显示分区边界。若关闭VIS/RAD编译后重载门户文件,可快速观察修改效果。

游戏内检查方法:
- 控制台命令"mat_leafvis"
*mat_leafvis 3
:显示PVS 中所有分区轮廓 *mat_leafvis 1
:仅显示当前分区轮廓(需开启sv_cheats)
- 使用mat_wireframe查看几何体渲染:
* mat_wireframe 1
:显示PVS 中的多边形绘制(需开启sv_cheats)
提示分割
当分区可见性不理想时(如左图所示所有分区相互可见),需使用提示分割:将特殊材质tools\toolshint
应用于笔刷表面可分割相交分区(无需分割的面应使用tools\toolsskip
)。示例中沿紫线放置提示分割后,分区1和3将恢复为首图的理想状态。
提示分割会产生额外分区(如图右侧将出现三个新分区),但性能影响有限。
Detail笔刷
func_detail是内部实体 ,可使编译器在计算可见性时忽略指定笔刷(同时保留其他功能)。地图中常有大量笔刷转为Func_detail笔刷 。
无绘制表面
若玩家在非作弊/旁观模式下无法看到某笔刷面,应为其应用特殊材质toolsnodraw((存在于 之中))或NULL纹理((存在于
之中))。无绘制表面会在编译时移除(不影响可见性计算),既减少渲染负担又缩小地图文件体积(无需计算光照贴图 )。
注意:
- 接触虚空(地图外部)的面无需无绘制
- 同一实体(含世界实体)内相邻笔刷面无需无绘制(详见Brush#In-game )


func_detail
合并,因此紧密接触的detail笔刷面无需无绘制(除非使用透明材质)。(存在于

区域门户 (仅存在于
起源 之中)
当提示分割无效时(如左图所有分区互见),应在关键通道口创建区域门户 。这会强制引擎进行逐对象视线检测(虽违背BSP/分区系统的初衷),但由于检测仅当摄像机看向门户时触发,若能遮挡足够多对象仍可提升性能。
图示四个门户位置中,通常仅需在右侧大型开口设置门户,走廊部分可保持原样。(理论上可用大量精确角度的提示分割实现类似效果,但得不偿失。)



遮挡器 (仅存在于
起源 之中)
当需要隐藏分区系统无法处理的模型时(如可破坏墙体后的高消耗角色模型),可使用遮挡器 。启用后,它会隐藏其后方的模型(非笔刷),且应完全嵌入不透明物体内。
通过Propper 等工具将笔刷转为模型后,可用遮挡器隐藏更多内容(建议在detail笔刷 上操作)。
绘制距离
对于无遮挡的开放区域,除减少细节外,还可使用雾效 配合farz
参数控制绘制距离。
选择性淡出设置:
- 通过
Start/End Fade Dist/Pixels
键值 控制prop_static等实体的淡出 - 根据
Screen Space Fade
选择按单位距离或屏幕像素计算
淡出距离差值建议设为200,既保证视觉效果,又避免过长过渡带增加渲染排序负担。
特殊实体func_lod也可淡出,但其关联笔刷不能用于其他实体。
示例地图
sourcesdk_content\hl2\mapsrc\
sdk_func_detail.vmf
sdk_hints.vmf
sdk_occluders.vmf