3D引擎中LOD技术的理论基础

时间:2022-07-26
本文章向大家介绍3D引擎中LOD技术的理论基础,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

虚幻引擎中细节优化相关的技术有 level of details 和 level streaming 两种,他们的共同点在于:当相机视角靠近某一片区域时,那里的细节才会被临时加载,从而节省资源(cpu,内存,外存)。

  • level of details:或LOD,细节层次,给每个网格体准备不同视距下的形状
  • level streaming:类似Photoshop的图层概念,将物体分入不同的场景,选择性加载

level streaming技术在上一篇《虚幻引擎之场景动态加载》讲过了,本文介绍LOD技术:

  1. Level Of Details:细节层次
  2. 手动LOD导入
  3. 自动LOD生成
  4. LOD碰撞检测的一致性
  5. LOD打包:选择性降级

Level Of Details:细节层次

理论基础:当物体远离眼睛(相机)时,它占用的屏幕像素减少,许多几何细节(三角形)有所删减,但每一帧仍然计算它全部的细节,被删减的那部分所占用的算力被浪费。此时可以准备一个“删减版”的几何体,替代“完整版”的几何体,节省计算资源(cpu/gpu)的同时,屏幕上的输出效果一样。但存储LODs需要额外的一些内存资源。

LOD技术的应用场景在于,当一个mesh占用屏幕像素很小时(如相机远离mesh),减少mesh的三角形数,节省资源。随便打开一个static mesh,进入mesh编辑器,默认处于LOD0。LOD0是最高细节的lod,拥有最多的三角形和点数,LOD1、LOD2依次递减。引擎根据mesh占用屏幕的像素与屏幕像素的比例来实时判断与切换不同层级的LOD,这个比例叫screen size。

https://docs.unrealengine.com/en-US/Engine/Content/Types/StaticMeshes/HowTo/LODs/index.html

手动LOD导入

在mesh编辑器的detail面板中可以导入fbx等3d模型,同时设置Screen Size。比如当一个mesh离屏幕非常远时想要自动隐藏,可以导入一个空的网格体,然后设置screen size为很小的值(比如0.01)。

mesh editor >> Details >> LOD Settings >> LOD Import

https://docs.unrealengine.com/en-US/Engine/Content/Importing/FBX/HowTo/ImportingLODs/index.html

自动LOD生成

理论基础:和手动导入的lod不同,自动生成的lods全部基于lod0,可以被临时计算出来,无需存储,从而可以减小打包后的体积(节省外存)。官方推荐的做法是自动生成LOD,因为引擎为我们提供了基于四叉树的边坍缩算法,可以根据不同的screen size,自动生成不同层级的lod,我们只需要设置lod的数量即可。

Tip:设置了自动LOD以后,移动相机几乎察觉不到lod的切换(这也是lod的本意),但可以通过viewport左上角的实时数据来观察效果。

mesh editor >> Details >> LOD Settings >> Number of LODs

既可以手动调lod参数,也可以使用模板快速创建lods,引擎提供了几个可用的模板,在LOD Group中可以选择(会覆盖当前设置)。想修改默认的模板,需要修改相应的引擎参数:

mesh editor >> Details >> LOD Settings >> LOD Group

模板文件路径:

[project] >> Intermediate/ >> Config/ >> CoalescedSourceConfigs/ >> Engine.ini >> [StaticMeshLODSettings]

1.[StaticMeshLODSettings]
2.LevelArchitecture=(NumLODs=4,LightMapResolution=32,LODPercentTriangles=50,PixelError=12,SilhouetteImportance=4,Name=LOCTEXT("LevelArchitectureLOD","Level Architecture"))
3.SmallProp=(NumLODs=4,LODPercentTriangles=50,PixelError=10,Name=LOCTEXT("SmallPropLOD","Small Prop"))
4.LargeProp=(NumLODs=4,LODPercentTriangles=50,PixelError=10,Name=LOCTEXT("LargePropLOD","Large Prop"))
5.Deco=(NumLODs=4,LODPercentTriangles=50,PixelError=10,Name=LOCTEXT("DecoLOD","Deco"))
6.Vista=(NumLODs=1,Name=LOCTEXT("VistaLOD","Vista"))
7.Foliage=(NumLODs=1,Name=LOCTEXT("FoliageLOD","Foliage"))
8.HighDetail=(NumLODs=6,LODPercentTriangles=50,PixelError=6,Name=LOCTEXT("HighDetailLOD","High Detail"))

例如,“SmallProp”模板的效果如下:

https://docs.unrealengine.com/en-US/Engine/Content/Types/StaticMeshes/HowTo/AutomaticLODGeneration/index.html

LOD碰撞检测的一致性

lod只是在屏幕上的输出做优化,并不影响它的碰撞属性,不同层级的lod的碰撞属性必须一致,通常是基于LOD0(即物体本来的形状)

mesh editor >> Details >> General Settings >> LOD for collision

https://docs.unrealengine.com/en-US/Engine/Content/Types/StaticMeshes/HowTo/LODCollision/index.html

LOD打包:选择性降级

理论基础:对于某些低端平台,可能用不到lod0,甚至lod1,可以选择性删除最高级的lod以节省内存/外存空间。

  • 节省内存(运行时):mesh editor >> Details >> LOD Settings >> Minimum LOD
  • 节省外存(打包后):[project] >> Config/ >> DefaultEngine.ini >> [Console Variables]

在[Console Variables]字段下的代码:

1.[ConsoleVariables]
2.; Strip render data for LODs below the MinLOD for the target platform during cooking.
3.r.StaticMesh.StripMinLodDataDuringCooking=1
4.r.SkeletalMesh.StripMinLodDataDuringCooking=1

https://docs.unrealengine.com/en-US/Engine/Content/Types/StaticMeshes/HowTo/StripUnUsedLOD/index.html

<完>