乐趣区

关于ios:厚积薄发Unity-Batches与glDrawElements的关系

1)Unity Batches 与 glDrawElements 的关系
​2)渲染大面积草地时,如何降低消耗
3)HUD 随着摄像机偏移
4)Unity 中如何在竖屏模式的 UI 之上显示强制横屏的 UI
5)iOS 能耗问题


这是第 222 篇 UWA 技术常识分享的推送。明天咱们持续为大家精选了若干和开发、优化相干的问题,倡议浏览工夫 10 分钟,认真读完必有播种。

UWA 问答社区:answer.uwa4d.com
UWA QQ 群 2:793972859(原群已满员)

Rendering

Q:Unity 里用 FrameDebug 显示 DrawCall 是 422 个,Batches 是 435 个,在 SnapDragonProfiler 里抓取进去 glDrawElements 数目是 1449 个,怎么了解这种差别?

A1:可参考以下几点:

  1. 题主的数据有一点问题,DrawCall 数目应该大于等于 Batches。依据特定的规定,多个 DrawCall 能够视为一个 Batch,一个 Batch 中蕴含多个 DrawCall,节俭了一部分 CPU 提交数据的操作。
  2. 调用 glDrawElements 函数进行绘制就是 DrawCall 的一种模式。

感激 Vest@UWA 问答社区提供了答复

A2:这部分能够参考 UWA Day 2020 里张强老师的分享《Unity 移动游戏我的项目优化案例剖析(上)》中的第二大节。

感激范君 UWA 问答社区提供了答复


Rendering

Q1:渲染大面积草地时,如何降低消耗?

A1:有以下几点:

  1. 应用 DrawMeshInstance。
  2. 下面这个 API 是不会进行视距剔除,视锥体剔除和遮挡剔除的。

上面有两种计划:
a. 将草地按区域分组,用每组的中心点计算视距,根据间隔切换网格 LOD 或剔除。
还能用向量点乘简略剔除在相机前方的草地。(留神临界问题)
b. 借助 CullingGroup。
CullingGroup.onStateChanged 事件绑定,通过事件触发调整传入 DrawMeshInstanced 的 Matrix 程序和渲染数量。(比拟难的是,DrawMeshInstanced 只能指定渲染前几个 Matrix)

通过 cullingGroup.SetBoundingSpheres 实现视锥体剔除和遮挡剔除;
通过 cullingGroup.SetBoundingDistances 实现视距剔除和 LOD;
这个计划也最好进行区域分组,不然 CullingGroup 的事件监听占用会比拟高。中端机上 4000 个监听会占约 2ms。

当前如果有比照两种计划的性能,我再进行补充。
附:
CullingGroup API 的应用阐明

Unity 3D 研究院之 Lightmap 反对 GPU Instancing

如何高效应用 GPU Instancing 技术来进行草丛渲染

降级 Unity 2018 过程中,遇到的 DrawMeshInstanced 不失效的问题

感激题主李先生 @UWA 问答社区提供了答复

A2:能够应用 Indirect 模式的 Instancing,配合 ComputerShader 实现视锥剔除和遮挡剔除。

感激邹春毅 @UWA 问答社区提供了答复

Q2:手机上能用吗?

A:举荐一个应用 URP 制作的草海成果,亲测可在 Mobile 端应用。
Unity URP Mobile Draw Mesh Instanced Indirect Example

性能测试:

  • can handle 10 million instances on Samsung Galaxy A70 (GPU = adreno612, not a strong GPU), 50~60fps, performance mainly affected by visible grass count on screen(draw distance = 125)
  • can handle 10 million instances on Lenovo S5 (GPU = adreno506, a weak GPU), 30fps, performance mainly affected by visible grass count on screen(draw distance = 75)

感激 Vest@UWA 问答社区提供了答复


Rendering

Q:HUD 为什么会随着摄像机偏移?

代码如下:

    Vector3 midVe1   = obj.transform.position;
    Vector2 viewPose = worldCamera.WorldToViewportPoint(midVe1 + new Vector3(0, 2, 0));
    viewPose.x *= Screen.width;
    viewPose.y *= Screen.height;
    hud.anchoredPosition = viewPose; 

图片如下:

A:题主说的这个景象是正当的。

Vector2 viewPose = worldCamera.WorldToViewportPoint(midVe1);
Vector2 viewPose = worldCamera.WorldToViewportPoint(midVe1 + new Vector3(0, 2, 0)); 

这两个算进去的 viewPos.x 是不一样的。所以能够改成先算 x,再偏移 y。大略是这样:

Vector3 midVe1 = obj.transform.position;
Vector2 viewPose = worldCamera.WorldToViewportPoint(midVe1);        
viewPose.x *= Screen.width;
viewPose.y *= Screen.height;
viewPose.y += 130;
hud.anchoredPosition = viewPose; 

这外面 y 方向上的偏移值(130)就要本人调整了。

感激 Xuan@UWA 问答社区提供了答复


UGUI

Q1:针对 Unity 中如何在竖屏模式的 UI 之上显示强制横屏的 UI,咱们当初有两种思路:

1. 改 Screen.orientation 之后再显示。
– 须要思考外层 RectTransform 是否曾经“实现”了转屏导致的变动,而后能力去适配内层。尚未找到牢靠的事件。
– 须要解决背景,半透明背景可能透出前面的 UI 排版凌乱。

2. 将新 UI 旋转依 z 轴转 -90 度显示。
– 对刘海屏的适配须要做相应的批改。
– 无奈转屏(因为还是竖屏,且不反对 Upside Down)。然而这个应该能够克服。

请问,两者哪种更好呢?

A1:一个简略的形式:
Canvas 的 RenderMode 改成 World Space,管它摄像机怎么裁剪,UI 画布也不会发生变化。

如果自适应不了,在 Canvas 上依据你本人的需要做好自适应就好。

感激郑骁 @UWA 问答社区提供了答复

A2:咱们之前我的项目里刚好有个相似的需要,在横屏游戏中,个别玩法切换到竖屏。

过后采纳的解决方案是批改 Screen.orientation,同时批改 UI 全局根节点上的 CanvasScaler 的 referenceResolution(竖屏时设置为 1080,1920,横屏设置为 1920,1080),matchWidthOrHeight(和我的项目的适配策略相干,竖屏时设置为 0,横屏时为 1),切换时会有一个全屏遮罩的 fade 成果,来防止切换时显示谬误。

感激范君 @UWA 问答社区提供了答复

Q2:请问为什么不思考转 90 度的做法?

A:咱们过后没有测过旋转的计划。当初大略想想有两个问题,不晓得想的对不对。

  1. 单纯旋转角度应该只能在横屏的两头局部显示一个竖屏界面吧?感觉还须要其余解决。
  2. 对工作流是否有影响,如果要一个竖屏界面是否是要在制作时先做成一个横屏界面?外部控件是否要解决?例如最终呈现出竖屏成果的剧情文字从左到右呈现,旋转之前应该是横屏的从下到上呈现,同时每个繁多文字也是旋转的。

感激范君 @UWA 问答社区提供了答复

Q3:RectTransform 的尺寸会被提早批改这件事,没有造成什么问题么?

A:记不太清了,印象中没有遇到什么大问题。不过咱们过后这类需要切换时都是全屏 UI,加了遮罩 Fade 后没有什么显著的穿帮。

感激范君 @UWA 问答社区提供了答复


iOS

Q:我在 Xcode 真机调试中发现能耗始终处于 Very High,而我我的项目的根本状况是(每帧 GPU 渲染 3.5ms,每秒 60 帧,渲染分辨率为 750*1624,设施 iPhone XS,场景中只有 UGUI 没有其它 3D 或 2D 物体),麻烦大家帮忙看看这个电量耗费属于失常吗?还有没有优化的空间(帧数和分辨率预计是没有方法降落了,会影响我的项目成果),谢谢。

A1:测试过空场景 Average Energy Impact 也会显示 Very Hight(如下图),题主的 GPU 能耗占比拟大阐明 CPU 相对而言还是压力比拟小的:

这个帖子也是相似的问题,看上去是因为 Unity 引擎自身绝对于一般 APP 体量较大,所以能耗体现较高,升高指标帧率会有所改善。

Energy Impact 表征的是全局(非单个 APP)的能耗,而且测试的时候 USB 连贯充电是如何在统计中防止的不太分明机制,倡议应用 Xcode Instruments 工具的 Energy Log 模版测一下单个 APP 的能耗状况。
Energy Log 文档

对于能耗的优化先关注整体的是 GPU 还是 CPU(或其余方面),GPU 的用 FrameCapture 定位一些比拟高耗时的 Shader 进行优化,CPU 联合 Time Profiler 模版定位一些高能耗的 CPU Bound。

感激羽飞 @UWA 问答社区提供了答复

A2:GPU 的用 FrameCapture 定位一些比拟高耗时的 Shader 进行优化。
要害是 Capture 哪一帧,这个会很自觉。

感激山中千年 @UWA 问答社区提供了答复

封面图来源于网络


明天的分享就到这里。当然,生有涯而知无涯。在漫漫的开发周期中,您看到的这些问题兴许都只是冰山一角,咱们早已在 UWA 问答网站上筹备了更多的技术话题等你一起来摸索和分享。欢送酷爱提高的你退出,兴许你的办法恰能解他人的当务之急;而他山之“石”,也能攻你之“玉”。

官网:www.uwa4d.com
官网技术博客:blog.uwa4d.com
官网问答社区:answer.uwa4d.com
UWA 学堂:edu.uwa4d.com
官网技术 QQ 群:793972859(原群已满员)

退出移动版