异步数据流
数据流是一种优化技术,旨在减少加载图形资源引起的峰值。使用这种技术,并不是所有的数据都一次加载到内存中。相反,只加载所需的数据,其余的根据需要逐步加载。
在单独的异步线程中执行资源加载并将其传输到GPU。之后,资源被同步并添加到CPU侧的虚拟场景中。
在UNIGINE中,异步数据流是默认启用的。您可以在UnigineEditor或通过控制台禁用异步数据流:
- 在UnigineEditor中,打开Settings窗口并转到Streaming部分。在这里您可以为纹理和/或网格切换流模式。
- 在控制台中,运行相应的命令,切换纹理和/或网格的流模式。
有两种主要的流模式:异步(Async)和强制(Force)。Force模式确保同时加载每帧所需的所有资源(例如,抓取帧序列,渲染节点预览,预热等)。
流系统提供以下数据异步加载到RAM:
- 所有纹理运行时文件和启用了Unchanged选项的纹理,包括立方体图, 体素探针图和烘烤阴影的阴影地图。
- ObjectMeshStatic, ObjectMeshClutter, ObjectMeshCluster, ObjectGuiMesh对象的网格,以及DecalMesh。
过程生成的对象,如ObjectMeshClutter是在一个单独的线程中生成的,这大大降低了性能成本。
可以通过使用render_streaming_meshes_info和render_streaming_textures_info控制台命令获取流资源的一般信息。
还可以通过使用render_streaming_meshes_list和render_streaming_textures_list控制台命令输出已加载资源的列表和有关它们的详细信息。
异步着色器编译#
除了网格和纹理的异步加载之外,流系统还提供了异步着色器编译和加载。
也有2种模式:异步(Async)和强制(Force)。 在强制模式下,当前帧所需的所有着色器都在当前线程中同时编译并加载到RAM中。 默认情况下,使用异步模式。
编译和加载的着色器的数量在Performance Profiler工具中可用。
内存使用限制#
图形资源的所有内存分配都受提交内存大小的限制,其中包括RAM和VRAM。
您可以限制应用程序可用的内存,以避免崩溃,并在性能和内存消耗之间找到平衡。这里有两个主要参数:
- RAM和VRAM的使用限制,将内存消耗限制在已提交内存的指定百分比内。但是,您应该记住,如果流媒体系统超过了VRAM使用限制,它将开始使用RAM加载图形资源。如果超过RAM使用限制,应用程序将崩溃。
- RAM和VRAM的空闲空间,它定义了每帧额外为分配保留多少内存。这些参数确保在当前帧中总是有足够的内存来加载资源。这些值应该根据应用程序的实际情况来确定。
您可以通过UnigineEditor或控制台指定使用限制和可用空间:
- 在UnigineEditor中,打开Settings窗口,转到Streaming部分,并指定所需的值。
-
在控制台中,将所需的值传递给相应的命令:
纹理流#
流系统自动管理纹理。 纹理流有两种模式:
- 提供纹理异步加载的Asynchronous模式。
- Forced模式,用于一次强制加载当前帧所需的纹理。
对于纹理流优化,您可以启用纹理mipmap加载,这通过减少纹理流的内存消耗来显着提高性能。 此功能允许在当前时刻加载正确的mipmap。 启用mipmaps加载后,将卸载当前未使用的纹理。
要通过UnigineEditor启用和配置mipmap加载,请执行以下操作:
- 打开Settings窗口并转到Streaming部分。
- 切换Mipmaps标志并指定所需的Mipmaps Density。
Mipmaps Density设置相对于屏幕分辨率的mipmap的密度,并帮助定义当前应该加载哪个mipmap。您可以为不同的质量预设指定不同的值。例如,对于低质量预设,可以将密度设置为小于1。在这种情况下,引擎将加载低分辨率的mipmaps,纹理将看起来模糊。
此外,您可能需要为某些材质中的每个纹理配置Texture Streaming Density Multiplier以实现所需的视觉效果。
后效材质中纹理的强制流式处理#
为了确保所有后期效果的纹理在需要时可用,默认情况下为所有后期材质设置强制流模式。您可以在Material Editor中找到这个设置。
但是,如果后期素材中的一些纹理持续变化(通过代码、Tracker等),建议为每个纹理指定强制流模式:
- 在Material Editor中,在后期效果材质的Textures Streaming Mode参数中设置Setting For Each Texture。
- 在材质Material Editor的Parameters面板中单独切换每个纹理的强制流。
这些设置覆盖了在Settings窗口中指定的全局纹理流设置。
网流#
网格可以分别加载到RAM和VRAM中,以便更有效地处理几何图形。这允许消除内存泄漏:参与碰撞和交叉点的网格只能加载到RAM中,如果它们当前没有渲染。
有两种模式的网格流到RAM/VRAM:
- 异步模式,提供网格的异步加载。
- 强制模式,用于立即加载当前框架所需的网格。
异步加载到RAM和VRAM是不同的。即使网格没有及时加载到显存,它也不会影响应用程序的行为(您可能只会注意到一些延迟)。但是,如果网格没有及时加载到内存中,可能会导致场景中对象的物理行为不正确。
首先,我们强烈建议您使用形状进行碰撞和交叉检测,因为它更快。如果由于某种原因,它不适合您的项目,请使用以下方法:
- 加载网格并在它们存在时将它们保存在内存中。一些基于网格的对象的API提供了开箱即用的功能。它可以部分解决不正确行为的问题,然而,只有少数网格可以保持加载。
-
使用预取系统,允许在使用之前异步预加载参与碰撞和交叉点的网格到内存:
- 设置Radius预取模式。
- 指定物理半径(碰撞)和/或计算交集的半径。
- 指定应该超过碰撞和交叉半径值的预取半径。
您也可以预加载计算碰撞和交叉的所有网格(Full预取模式),但是这会显著增加RAM的使用。
- 一些基于网格对象的API,以及MeshRender类API也提供了允许实现预加载网格的自定义预取逻辑的方法。
异步流网格不应该被修改。改变这种网格的唯一方法是使其程序化。过程网格是通过代码创建的网格,这样的网格有一个特定的流模式:它总是在创建后保存在内存中,并且永远不会卸载,直到对象被代码破坏或网格返回到其正常模式(从源文件流)。基于网格的对象API允许将网格切换到过程模式并应用更改。