赞
踩
https://zhuanlan.zhihu.com/p/105616808
现在手游是越做越大,大世界似乎已经成为mmo游戏的基本配置了,然而,大世界需要解决的东西非常多。
网上的资料也比较少。BatchRendererGroup就完美解决了这一问题,并且还带来了多线程做Cull和LOD的好处。
BatchRendererGroup使用非常简单,构造,AddBatch,GetBatchMatrices,就这三个接口就够了。
构造函数:
这个构造函数,是传入一个Cull函数,这个Cull函数我们后面讲,大部分功能都在里边。
AddBatch函数:
https://docs.unity3d.com/ScriptReference/Rendering.BatchRendererGroup.AddBatch.html
大部分参数都是一目了然,我主要说几个需要注意的参数,一个是Bounds,这个的意思是用来控制这个Batch的显示和隐藏,他会跟相机做Cull运算,一般我们取你所有BoundingBox的合集。还有一个会填入MaterialPropertyBlock,这个可以用来做GPUInstance,传入Block变量在Shader中使用。
这里有个int返回值,这个相当于一把钥匙,标记当前Batch在BatchGroup的Index。
我们需要使用这个Index来用我们的第三个接口GetBatchMatrices,这个会获取矩阵列表,标记Mesh的Transform信息,我们需要往里填入矩阵。
接下来我们大部分工作都是在Cull里边进行了。
Cull的方法定义是这样的
JobHandle OnPerformCulling(BatchRendererGroup rendererGroup, BatchCullingContext cullingContext)
两个参数,BatchRendererGroup,这个就是你构造的那个Group,这个是用来区分可能你同一个Cull函数会生成多个Group,第二个BatchCullingContext,这个是你需要填入的Cull结果。BatchCullingContext有四个变量
// // 摘要: // Planes to cull against. public readonly NativeArray<Plane> cullingPlanes; // // 摘要: // See Also: LODParameters. public readonly LODParameters lodParameters; // // 摘要: // Visibility information for the batch. public NativeArray<BatchVisibility> batchVisibility; // // 摘要: // Array of visible indices for all the batches in the group. public NativeArray<int> visibleIndices;
前两个只读的变量是给我们的信息,第一个是相机的六个面,第二个是LOD参数,里边也是相机的参数,诸如正交还是透视,FOV这些。
下面两个参数是我们需要填入的Cull结果。
上面的是标记可视物体总数以及一些只读的信息,下面这个是可视物体的Index,标记第几个是可视的。
最关键的地方是这个可以返回一个JobHandle,也就是说可以利用Unity的JobSystem。
有了上面的理论基础,我们开始着手解决我们的问题。
以植被为例,思路是这样的:
我们把所有的植被信息,包括植被的平移,旋转,缩放,颜色(或其他GPUInstance的变量)Mesh,LodMesh,Lod信息,材质等等,保存成Asset,在游戏运行时,这部分GameObject就可以删掉了。
我们拿到Asset后开始构造RenderBatchGroup,通过Asset里的GPUInstance变量构建Block给Shader使用,然后将LodMesh和Mesh分别使用AddBatch添加,通过平移,旋转,缩放,构建矩阵填入Batch,剩下的工作就是在Cull多线程执行Cull工作了。Cull的原理也比较简单,一个是LOD决定显示哪一级,一个是视椎体裁剪。
基本就两个批次,当然这里得用强大的URP Batch和GPUInstance配合使用。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。