Unity 在配置 LodGroup 时,其分级切换的计算方法是按照物体在相机视野中占据的比例计算的。在运行时,如果相机视野范围(Field of View)没有改变,那么这个值可以直接换算成物体距离相机的距离。这里就讨论下如何计算得到这个距离。
1、LODGroup 切换判定的原理
渲染部分就跳过,这里只讲 Unity 计算 Lod 切换判定的原理,如下图所示:
绿色区域为视野范围,蓝色 GameObject 为目标物体,Unity 计算的值就是 GameObject 的尺寸与当前相机视野的比例,即 Size / ViewDistance ,并以此为标准进行 LOD 的切换。
我们在 LOD Group 中可以进行配置分级比例:
以上图为例,就是当 Object Size 占比小于 49.97% 时切换到 Lod1,小于 22.8% 时切换到 Lod2,以此类推。
这个是物体的缩放为 1 的情况,实际计算时也要考虑物体的缩放对屏幕占比的影响。
2、计算方法
显然在相机的 Field of Veiw 不变的情况下,这个比例可以直接转换成物体距离相机的距离进行简单计算(Camera Distance)。一般情况下,为了节约性能,都是采用判定相机到物体的距离来进行 LOD 裁剪。
计算原理就是简单的三角函数,代码如下:
Mesh mesh;//自行获取网格
LODGroup group;//自行获取LOD Group
LOD[] lods = group.GetLODs();
//这里是按scale为1算的,实际计算要侧乘上缩放值
float3 size = mesh.bounds.size;
//unity 是取最大值,而不是对角线长度
float objectSize= math.max(math.max(size.x, size.y), size.z);
//根据相机的配置获取相机角度(弧度制)
float cameraAngle = math.radians(CameraFieldOfView * 0.5f);
//计算当物体刚好所占屏幕比例为 1 时,距离相机的距离;
float cameraRatio = objectSize* 0.5f / math.tan(cameraAngle);
//根据相似三角形原理和 LOD Group 配置,分别计算出多级lod物体距离相机的距离
if (lods.Length > 0)
x = cameraRatio / lods[0].screenRelativeTransitionHeight;
if (lods.Length > 1)
y = cameraRatio / lods[1].screenRelativeTransitionHeight;
if (lods.Length > 2)
z = cameraRatio / lods[2].screenRelativeTransitionHeight;
if (lods.Length > 3)
w = cameraRatio / lods[3].screenRelativeTransitionHeight;
计算完成之后的lod就可以保存下来,只要相机不变就不用再计算了。