Unity基于JobSystem的流式LODGroup

目录

简介

功能展示

性能测试

与Unity自LODGroup对比

技术详解

简介

    Unity自带LODGroup是黑壳的东西,我们无法做到修改其代码(买源码的例外),在手游项目中往往要控制游戏内存的增长,是否可以从常驻内存的LODGroup入手??这里作者就写了个流式的LODGroup。

    源代码:GitHub - aganwenqi/LODGroup

功能展示

    展示LOD结构

常驻内存

流式加载

常驻内存和流式加载混合

大批量流式

性能测试

    测试手机:魅蓝note6,处理器高通骁龙625

    数量:使用400个LODGroup常驻内存测试。

    计算代码:将计算LODGroup屏占比的代码放在JobSystem下计算。

如下图,JobSystem下的计算一个作业0.09ms基本封顶,一次JobSystem的计算0.185ms封顶,主线程创建Job作业的时间最高不超过0.03ms,所以JobSystem消耗非常小。

    如下图,每帧计算屏占比耗时基本都是2ms左右,JobSystem上面说了消耗非常小,主要是准备数据给JobSystem计算和计算完状态改变所带来的消耗(仓库最新版已使用缓存机制解决2ms耗时)。

    下图是没有经过JobSystem计算的方式,效果3ms。

    跟Unity自带的对比,由于不知道在Proflier中自带的字段是哪一个,也许压根就没有暴露出来,所以不能直接对比,通过看总体时间轴的延迟,基本上没什么太大区别,因此自带的计算一样很快。

与Unity自LODGroup对比

UnityLODGroup

作者LODGroup

内存占用

=

<

计算速度

=

=

常驻内存

流式加载

-

混合模式

-

源代码开源

-

技术详解

屏占比的计算

    如下图,根据相机距离LOD Group的距离、LODGroup包围盒大小与摄像机的看到到它这个位置的视野大小做对比计算出relativeHeight。

    通过滑动图下的指针场景视图的相机位置也会根据滑动的位置移动相应的位置。

    这里我们将上面的计算做反向计算既可以得出。这里正切要换成60,这样计算出相对于半个size对应的distance,而relativeHeight是滑动条提供的,这个值是size与相机到LODGroup这个位置摄像机看到的size对比。

    因此就有:size*Tan60°对应的distance /真正的distance = size / 相机到LODGroup这个位置摄像机看到的size对比视野大小,而size / 相机到LODGroup这个位置摄像机看到的size对比视野大小 = relativeHeigh。

流式加载

    这算本作品中的一大亮点,本次设计中每个LODGroup里的每层都是可以单独流式加载的,且每级LOD切换是无缝的,只有要切换的LOD加载出来当前的LOD才可以卸载。

根据权重优先加载

    如下图,每一级LOD都可以设置加载权重。

例如下图3组LODGroup设计如下。

   

    首先将最高优先级的层先挑选出来,优先考虑加载。

权重筛选后再根据距离优先

    下图距离越近的将越优先被送去加载

   

流式加载控制

    如下图,可以在配置上设置同时异步加载数量,设置将会保存到配置文件中在运行的时候加载出来。如下设置4个那么同一时刻只允许有4个在加载。

   

  • 6
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 9
    评论
使用Unity的Job System来构建Mesh可以提高游戏的性能,因为它可以在多个CPU核心上同时处理数据。 首先,你需要为你的Mesh数据创建一个结构体,以便Job System可以处理它。例如,你可以创建一个包含所有Mesh数据的结构体,如下所示: ``` struct MeshData { public Vector3[] vertices; public int[] triangles; ... } ``` 接下来,你需要创建一个Job,用于生成Mesh。你可以使用IJobParallelFor或IJobForEach来处理每个顶点或三角形。例如,如果要处理每个顶点,可以编写以下代码: ``` struct GenerateMeshJob : IJobParallelFor { public MeshData meshData; public void Execute(int i) { // Generate vertex data meshData.vertices[i] = ... } } ``` 然后,你需要在主线程中分配和初始化MeshData结构体,并将其传递给Job: ``` var meshData = new MeshData(); // Initialize meshData vertices, triangles, etc. var job = new GenerateMeshJob() { meshData = meshData }; var jobHandle = job.Schedule(meshData.vertices.Length, 64); ``` 最后,你需要等待Job完成,并将数据写入Mesh: ``` jobHandle.Complete(); var mesh = new Mesh(); mesh.vertices = meshData.vertices; mesh.triangles = meshData.triangles; ... ``` 需要注意的是,使用Job System构建Mesh需要一定的编程经验和技巧,因为它涉及到多线程编程和数据同步等问题。因此,如果你是新手开发者,建议先熟悉Job System的基本用法和原理,然后再尝试使用它来构建Mesh。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IChessChess

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值