Unity LOD Group

概述

当绘制对象时,单位像素绘制的三角形数量越多,效率就越低。因此我们希望在保证精度的前提下渲染尽量少的三角形数量,LOD可以解决这个问题。

LOD(Level of Detail),根据对象距离摄像机的距离,使用合适的渲染数据(Renderer,Mesh,Material)来对对象进行渲染。典型的,一个角色,当距离摄像机特别近时,我们希望展现更多的细节,比如布料纹理,花纹。但是当距离摄像机特别远时,即使渲染了这些细节,屏幕上也不一定能看到,因为这些细节可能比一个像素还要小,这些渲染就没有效果了。同时,近处栩栩如生的细节,到一定距离后,会产生像素抖动,例如衣服上耀眼的金线,在远处由于误差,可以一会渲染,一会不渲染,效果就是一些杂乱的亮点在闪烁,显得很脏。所以无论是为了降低渲染负载,还是降低像素抖动,当对象离我们较远时,都应该用简化的Mesh,简单的材质进行渲染。这就是LOD的作用。

题外话,其实对于其它部分,比如动画播放,AI更新,也是适用该概念的,远处的东西执行简化的逻辑。

在Unity中,使用 LOD Group 组件用来管理对象细节等级(Level of Detail)。

Unity LOD Group

Unity LOD Group控制LOD切换

Unity LOD GroupLOD选择条,选择LOD Levels,进行编辑,以及查看效果。

Unity LOD GroupLoad Bias质量设置信息。图中的信息表示当前设置为2.0,只要设置为1以外的值,都会出现该提示。在Editor>ProjectSettings>Quality>Other>LOD Bias进行设置。该值用来定义摄像机距离对象多远时,开始执行LOD逻辑。

Unity LOD GroupFade Transition Width,定义淡入淡出距离。当不选择Animate Cross-fading时,选择Culled前面的LOD,该参数会出现。主要是解决2个问题:浮点抖动,即由于浮点误差,摄像机和对象都不动时,在可见距离判断上不精确,结算结果一会可见,一会不可见,对象会闪烁。二是如果该判断范围太小,则相对距离在很小的范围内变化时,也会比较频繁地在可见,不可见之间切换,该width实际上定义了一个缓冲区来避免该现响。

Unity LOD Group该LOD级别进行渲染的Renderer,可以有多个。

此外,在该组件底部还有2个按钮

Recalculate Bounds:当添加进新的LOD Mesh Renderer 时,重新计算 Bounding Volume(包围体)。

Recalculate Lightmap Scale:当LOD包围体更新后,重新计算对象的所有的Mesh Renderers的 lightmap scale 属性。

LOD Group 选择条

LOD Group Selection Bar 用带颜色的框来表示选中的LOD。

LOD框内的百分数,是该LOD**的阈值,该阈值是对象在屏幕空间中的高度与屏幕总高度的比值。例如,如果LOD1的threshold被设置成了50%,则当拉远摄像机,到该对象在视口中的高度小于视口高度的一半时,显示该LOD。

Unity LOD Group

A:LOD预览的播放指示器。可以拖动摄像机图标来在LOD之间切换。在其底部显示了当前的百分比。

B:点击level框选中一个LOD,选中后,可以编辑两侧的框线来编辑其切换区域值,以及编辑显示用的渲染器(Renderers)。

C:在LOD框内,点击鼠标右键,会弹出菜单,可以删除该LOD,活在在LOD前插入新的LOD。

D:Level调整控制。拖动框的边线来改变LOD等级的百分比。

注意:如果 LOD Bias 的值不是1,则进行LOD切换时的摄像机位置可能不是对象在屏幕中高度比时的位置,所以会显示警告。

Unity LOD Group

预览 LOD 切换

当在Scene视口中选中一个对象,并用滚轮移动摄像机,或者直接在LOD Group 组件上拖动摄像机图标,可以看到距离多远时进行LOD切换。

Unity LOD Group

当切换LOD时,会渲染对象当前LOD的包围盒,以及当前LOD文字。

Unity LOD Group

Renderers for LOD Meshes

选中一个LOD后,可以编辑他的渲染模型。

Unity LOD Group

Renderers 是该LOD要进行渲染的Mesh,通常是挂载了LOD Group组件的对象的子对象。

点击Add按钮添,会弹出窗口,列表中是当前场景的所有对象,可以选择一个作为该LOD渲染的Mesh,也可以直接从Hierarchy窗口中直接拖动一个对象上去来添加,完成后该按钮变成一个Mesh预览,并显示“-”按钮来删除。同时后面会显示Add按钮。

如果添加的对象,不是该对象的子对象,Unity会提示将其编程子对象。

LOD切换

游戏过程中,我们不想让玩家明显地感觉到切换的过程,因此要实现一种平滑地切换。

当切换时,Unity会同时渲染当前和下个LOD地Mesh,并分别淡入和淡出。

Cross-fading 是同一时刻,用0-1地权重,渲染2个等级地技术。

Unity LOD Group

Unity实现了2种方式地切换,混色和半透明。

对于最后一个LOD,没有cross-fading,仅仅是淡出,后面没东西淡入了:)

设置平滑切换:

  1. Fade Mode 选择 Cross Fade。

Unity LOD Group

注意,如果使用了Speed Tree,请使用 Speed Tree 模式

  1. 默认地,Animate Cross-fading 是勾选的,意思是Unity会按照时间来执行淡入淡出。如果想要自定义根据摄像机位置的切换区域,取消该选项,并设置 Fade Transition Width参数来控制。

Fade Transition Width

当模型的高度比例到达下个LOD的阈值时,开始切换LOD,例如如果LOD1的阈值时60%,当高举比例为60%时,立即进行LOD0和LOD1之间的切换,切换会持续一定的时间。

Unity LOD Group

当勾选 Animate Cross-fading时,该过程是自动的,不需要进行任何设置。每个LOD切换执行同样的过程和时间。

也可以选择在LOD内定义其切换区域。Animate Cross-fading未选择时,该参数会显示。每个区域开始,并在下个LOD的阈值前结束。该区域定义的是在该LOD时,到达下个LOD差的百分比为多少时,开始执行(相当于提前进行)LOD的切换。

Unity LOD Group

设置方法:

  1. 取消 Animate Cross-fading 复选框
  2. 选择一个LOD,并调整 Fade Transition Width 的值。

Unity LOD Group

该值是当前LOD的整个长度的百分比。越大,开始的越早。

Working with Speed Tree mode

Speed Tree 的集合体为每个顶点存储了下一个LOD的位置信息,每个顶点知道如何在当前LOD位置和下个LOD位置之间进行插值。导入speed tree构建的模型时,Unity会自动选择Speed Tree mode。

Unity LOD Group

Unity只需要渲染当前的LOD几何体,并提供一个0-1的值来控制每个顶点逐步的移动到下一个LOD的位置。在LOD切换结束后,就变成下个LOD的几何体了。

Unity LOD Group

Speed Tree 模式用该 Blend Factor 对顶点位置,在当前Mesh LOD Level和下个Mesh LOD Level之间进行插值。用茶之后几何体进行渲染。

注意:Speed Tree 模式仅混合2个Mesh LOD levels,即它们都是Mesh Renderer。如果是切换到billboard片LOD级别或完全消失,则执行Cross-fading模式。

Blend Factors in Shader code

Unity并没有内建的提供混合两个Mesh的技术。如果需要,则要自己实现。

Unity会根据对象的屏幕尺寸计算混合因子,并传递给shader,存储在unity_LODFade.x中,y则是LOD Level。根据Fade Mode,在shader中对应LOD_FADE_PERCENTAGE和LOD_FADE_CROSSFADE。

API

编程接口