剔除(Culling)是Unity游戏开发时性能优化中非常重要的技术之一。

一、视锥剔除(Frustum Culling)

原理:Unity会自动跳过摄像机视野之外的对象渲染。

使用方式:这是Unity自带的一种剔除方式,无需设置。

二、遮挡剔除(Occlusion Culling)

原理:跳过被其他对象遮挡的对象的渲染

使用方式:这是常用的剔除方式,Unity中Window-Rendering-Occlusion Culling打开遮挡剔除面板,将需要剔除的对象标记为静态(Static),点击Bake

注意:遮挡剔除主要用于无大量动态物体的场景,遮挡剔除需要再运行时加载遮挡数据,因此需要确保内存充足。

三、细节层次剔除(LOD Culling)

原理:根据距离动态的降低对象的复杂度(即对象距离摄像头近的时候显示高精度模型,中等距离时显示中精度模型,远距离的时候显示低精度模型)。

使用方式:为需要剔除的对象添加LOD Group组件,然后为每个LOD层级分配要显示的不同精度的模型,Unity会根据距离自动切换LOD。

注意:细节层次剔除由于要显示不同精度的模型,因此需要为一个对象准备多个模型,一定程度上增加了内存开销。

四、层级剔除(Layer Culling)

原理:通过在摄像机(Camera)组件设置或脚本,可以选择性的剔除特定层级的对象。

使用方式:

Camera组件设置

脚本设置:

Camera.main.cullingMask=LayerMask.GetMask("Default","UI","Water");

五、距离剔除(Distance Culling)

原理:根据与摄像机的距离隐藏对象

使用方式:

注意:这种方式适用于开放世界游戏,远处的对象不需要渲染。

如果对象只有一个网格且没有其他精度模型,则使用距离剔除;如果对象有多个LOD层级,则使用LOD剔除。

六、面剔除(face Culling) 

原理:跳过对象正面或背面的渲染。(例如立方体的内部面不会被绘制)

使用方式:面剔除主要用于Shader,Unity中的Shader的面是否剔除,是由我们自己决定的,需要用到Cull语句:

        Cull Off:关闭剔除,正反面都渲染,

        Cull Back:剔除背面,

        Cull Front:剔除正面,

         默认的Cull是:Cull Back(剔除背面)

注意:Cull语句可以写在SubShader或Pass语句块中。

在最新版本Unity6中,面剔除变得更容易了,无需自行到Shader里面写Cull语句了,直接选中对象,在其材质面板的Render Settings-Render Faces中设置:

七、自定义剔除(Custom Culling)

原理:根据自定义规则禁用对象。

使用方式:例如对象与摄像头距离大于一定值时,让对象禁用。

注意:这种方式适合动态对象(如敌人或交互物体),但开销较大,因为需要在Update里面每帧调用。

八、阴影剔除(Shadow Culling)

原理:当场景中有大量的物体和光源时,计算每个物体的阴影会消耗大量的计算资源。阴影剔除的目的是在不影响视觉效果的前提下,尽可能减少不必要的阴影计算。Unity会剔除光源范围外的阴影。

使用方式:

        1.通过 Quality Settings 设置阴影距离:在 Unity 的 “Edit”(编辑)菜单下的 “Project Settings”(项目设置)中点击 “Quality”(质量)选项卡,找到 “Shadows”(阴影)部分。其中的 “Shadow Distance” 参数就是用于控制阴影绘制的最远距离,超出此距离的物体将不产生阴影。通过调整该值,可以根据场景大小和性能需求来优化阴影渲染,例如,对于大型室外场景,如果远处的阴影对整体效果影响不大,可以适当减小该值以提高性能。

        2.通过 Light 组件设置阴影范围:选择场景中的光源(如 Directional Light、Point Light 等),在其组件的属性面板中找到 “Shadows” 选项组。对于点光源和聚光灯,可以设置 “Range” 参数来控制其光照和阴影的有效范围,超出此范围的物体不会受到该光源的光照影响,自然也不会产生阴影;对于平行光,可以通过设置 “Culling Mask” 来选择哪些层的物体受该平行光影响产生阴影,从而间接控制阴影的范围。

        3.通过 Light 组件调整阴影投射:对于每个光源,在其属性面板的 “Shadows” 选项组中,可以通过 “Strength” 参数来调整阴影的强度,强度越低,阴影的视觉重要性就越低。对于一些对场景整体光照氛围影响较小的光源,可以适当降低其阴影强度,甚至将其设置为 0 来完全关闭阴影投射,从而实现基于重要性的阴影剔除。另外,还可以通过 “Resolution” 参数来调整阴影的分辨率,较低的分辨率会使阴影看起来更模糊,细节更少,但也能在一定程度上减少计算量,可以根据物体的重要性和距离相机的远近等因素来合理设置该值。

        4.通过脚本控制阴影投射:在脚本中,可以通过获取物体的 MeshRenderer 组件,然后设置其 “castShadows” 和 “receiveShadows” 属性来动态控制物体是否投射和接收阴影。例如,可以根据物体与摄像机的距离、物体的类型或当前场景的性能状况等条件,在脚本中编写逻辑来决定是否开启或关闭某些物体的阴影投射,从而实现更灵活的基于重要性的阴影剔除

九、GPU遮挡剔除(GPU Occlusion Culling)

这是Unity6及更高版本中的一项功能,这里暂时不过多介绍,可自行研究。

更多推荐